【技術書まとめ】『りあクト！ TypeScriptで始めるつらくないReact開発 第3版【Ⅱ. React基礎編】』を読んだまとめ

- JSXに埋め込めるのは式だけ
    - falsyな値だけでなくtrueも表示されない

> React ではカプセル化されたコンポーネントをベースとしてそれに必要なデータが宣言的に取得されるようにしておけば、model というデータの抽象化が必要かどうかというのは本質的な議論 にならない

- 変化の早い世界ではワンストップであることは技術の進歩の妨げになる
    - フルスタックではないことが逆に強みになる
- React Element はコンポーネントを任意の props で呼ぶための実行リンクのようなもの
    - 展開されていく
        - リアルDOM変換前の最終的な要素ツリーができる
            - メモリにキャッシュされる
                - これが仮想DOM
                    - 差分のみリアルDOMに反映する
- React の単方向データフロー
    - props が滝のように流れ落ちる
        - 関数型プログラミングと相性がいい
            - 数学的な純粋性
- フォーム
    - 「state のリフトアップ」
    - 親コンポーネントが state を持つ
        - state 変更関数を作る
            - 子コンポーネントに props として渡す
- コンポーネントのメンタルモデル
    - ReactElement で仮想DOMをつくる
        - パラメータ設定できるロジックブロックの化身
    - コンポーネント
        - JSの関数
            - props が引数、戻り値は ReactElements
            - state を持てる点が関数と違う
        - props と state が同じなら変わらない
            - どちらかが変わると戻り値も変わる
            - レンダリングが再実行される
                - props と state だけを見ていればいい
- props が大事
    - state は副作用がある
        - 純粋関数にしたい
            - 引数が同じなら同じ戻り値を返す関数
- `nullish coalescing`
    - なかったらこれを表示する
        - `{character.height ?? '???'}`
- ライフサイクル
    - `componentDidMount`
    - `shouldComponentUpdate`
    - `componentDidUpdate`
    - `componentWillUnmount`
- Hooksができた背景
    - `mixin`
        - コンポーネントとの依存関係を持ってしまう
        - 変数やメソッド名の名前の重複が起きやすい
        - 他の`mixin`同士が混ざって依存し合う
            - 削除の影響範囲がわからない
                - CSSみたい？
    - `HOC(Higher Order Component`
        - コンポーネントを引数にとりコンポーネントを返す
        - 外から状態やロジックを注入する関数と分ける
            - `Redux``Recompose`などで採用された
    - `Render Propsパターン
        - ReactElement を返す関数を props として受け取って自身のレンダリングに利用するコンポーネント
            - HOCへの批判
                - 名前衝突の危険性がある
                - props の型合成が面倒
        - ラッパー地獄
    - `Hooks`
        - HOCやrender props は設計パターンだった
            - Hooksは機能
        - 解決したこと
            - ロジック追加ごとにコンポーネントの階層が深くなる問題
                - 外に状態やロジックを持つ
            - 状態を伴った再利用可能なロジックを追加できる
            - ほぼ関数コンポーネントだけで作れるようになった
                - クラスコンポーネントの必要がほぼなくなる
                    - 機能ごとに副作用処理をまとめられる
                    - ストラングラーパターン
                        - 書き換える必要はない
- `useState`
    - 初期値をnullにするには？
        - `useState<User | null>(null)`
    - 前の値を使うときはアローで書く
        - `setCount(c => c + 1)`
        - ❌`setCount(count + 1)`
    - if の中に書いてはいけない
- 副作用とは
    - side-effect
        - コンポーネントの状態を変化させ、それ以降の出力を変えてしまう処理
            - `y = f(x)`で`f(1) = 2`が`f(1) = 5`になる
                - propsが同じでも出力内容が変わる
                    - レンダリングに同期させて実行するための`Hooks API`
                        - Effect Hook

```
const SampleComponent: FC = () => {
  const [data, setData] = useState(null);
  ...
  useEffect(() => {
    doSomething();

    return () => clearSomething();
  }, [someDeps]);
  ...
};
```

- `useEffect`
    - `clearSomething()`で外部の購読処理を解除する
    - `someDeps`は依存配列
        - 省略すると？
            - レンダリングごとに第一引数の関数が実行される
        - 空配列を渡すと？
            - 初回レンダリング時のみ第一引数の関数が実行される
    - 初期値レンダリングの後、副作用反映後の内容で再レンダリングされる
        - 副作用処理がコンポーネント表示をブロックしない
            - とりあえず何か表示されている
                - 処理中を伝える
                - レイアウト崩れを防ぐ
        - `useLayoutEffect`
            - 副作用処理が軽いもの
                - DOM要素・ブラウザ幅を取得してレンダリングに利用する
            - あくまで`useEffect`を使う
        - クラスコンポーネントとの違い
            - クラス
                - マウントでインスタンス生成
                - アンマウントまで生き続ける
                    - props や state は常に最新
                        - メンバー変数
            - 関数
                - レンダリングのたびに実行されては破棄される
                    - props や state は外から注入される
        - 機能凝集度が高い
            - 購読開始・切り替え・解除が`useEffect`内にまとめられる
                - 可読性が高い
                - 再利用しやすい
            - 「この処理はこの条件の時に実行されるべき」
- メモ化
    - 必要なときだけ計算して、結果をメモしておく
        - パフォーマンス最適化
            - 再レンダリングされるたびに実行されるのを防ぐ
    - `useCallback`
        - 関数定義そのものをメモ化する
    - `useRef`
        - 本来はリアルDOMと繋げるもの
        - 再レンダリングを伴わず何らかのデータを関数コンポーネントに保存したいとき使う

```
const timerId = useRef<NodeJS.Timeout>();
...
if (timerId.current)　clearIntervall(timerID.current);
```

- `Custom Hook`
    - `use`をつけて切り出す