React JSX 続き

https://qiita.com/y_ohr/items/18c2f658013906f3849c の続き

# 概要

TypeScript Deep DiveのReact JSXをやってみる。

https://typescript-jp.gitbook.io/deep-dive/tsx/react
https://basarat.gitbooks.io/typescript/docs/jsx/react.html

# React JSX Tip: Accept a component that can act on props and be rendered using JSX

関数コンポーネントやクラスコンポーネントをpropsに設定できる？
正直よくわかってないです。
とりあえず写経。
BabelでException発生。

```html:index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />

    <title>Hello React!</title>

    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
</head>

<body>
    <div id="root"></div>
</body>

</html>

<script type="text/babel">

    const X: React.Component<Props> = foo; // from somewhere

    // Render X with some props:
    ReactDOM.render(<X {...props}/>, document.getElementById('root'));

</script>
```

# React JSX Tip: Generic components

こちらもBabelでException発生。
雰囲気だけ。

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    /** A generic component */
    type SelectProps<T> = {item: T[] }
    class Select<T> extends React.Component<SelectProps<T>, any> { }

    /** Usage */
    const Form = () => <Select<string> items{['a','b']} />;
    ReactDOM.render(Form, document.getElementById('root'));

</script>
```

# Generic functions

アロージェネリック関数の場合は、`<T extends {}>`と書く。

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    function foo<T>(x: T): T { return x; } // OKay

    const foo = <T>(x: T) => x; // ERROR : unclosed `T` tag

    const foo = <T extends {}>(x: T) => x; // Okay

</script>
```

# React Tip: Strongly Typed Refs

Use.exampleRefに型を設定しているということ？

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    class Example extends React.Component {
      example() {
        // ... something
      }
    
      render() { return <div>Foo</div> }
    }
    
    
    class Use {
      exampleRef: Example | null = null; 
    
      render() {
        return <Example ref={exampleRef => this.exampleRef = exampleRef } />
      }
    }

</script>
```

レンダー付き。

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    class FocusingInput extends React.Component<{ value: string, onChange: (value: string) => any }, {}>{
      input: HTMLInputElement | null = null;
    
      render() {
        return (
          <input
            ref={(input) => this.input = input}
            value={this.props.value}
            onChange={(e) => { this.props.onChange(e.target.value) } }
            />
          );
        }
        focus() {
          if (this.input != null) { this.input.focus() }
        }
    }

    ReactDOM.render(<FocusingInput />, document.getElementById('root'));

</script>
```

# Type Assertions

`as Foo`を使う。
実装サンプルはなし。

# Default Props

`static defaultProps`で初期値を指定できるという話？

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    class Hello extends React.Component<{
      /**
       * @default 'TypeScript'
       */
      compiler?: string,
      framework: string
    }> {
      static defaultProps = {
        compiler: 'TypeScript'
      }
      render() {
        const compiler = this.props.compiler;
        return (
          <div>
            <div>{compiler}</div>
            <div>{this.props.framework}</div>
          </div>
        );
      }
    }

    ReactDOM.render(
      <Hello framework="React" />, // TypeScript React
      document.getElementById("root")
    );

</script>
```

FunctionComponentの場合。

```html:index.html
<!-- 省略 -->
<script type="text/babel">

    const Hello: React.FunctionComponent<{
      /**
       * @default 'TypeScript'
       */
      compiler?: string,
      framework: string
    }> = ({
        compiler = 'TypeScript', // Default prop
        framework
    }) => {
        return (
          <div>
            <div>{compiler}</div>
            <div>{framework}</div>
          </div>
        );
      };

    ReactDOM.render(
      <Hello framework="React" />, // TypeScript React
      document.getElementById("root")
    );

</script>
```

# 感想

- 結構難解な印象。慣れの問題？
- Reactが分からないのか、TypeScriptが分からないのか、分からなくなる。
- 少し自由に書いて理解を深めたい。

以上