- JSXに埋め込めるのは式だけ
- falsyな値だけでなくtrueも表示されない
React ではカプセル化されたコンポーネントをベースとしてそれに必要なデータが宣言的に取得されるようにしておけば、model というデータの抽象化が必要かどうかというのは本質的な議論 にならない
- 変化の早い世界ではワンストップであることは技術の進歩の妨げになる
- フルスタックではないことが逆に強みになる
- React Element はコンポーネントを任意の props で呼ぶための実行リンクのようなもの
- 展開されていく
- リアルDOM変換前の最終的な要素ツリーができる
- メモリにキャッシュされる
- これが仮想DOM
- 差分のみリアルDOMに反映する
- これが仮想DOM
- メモリにキャッシュされる
- リアルDOM変換前の最終的な要素ツリーができる
- 展開されていく
- React の単方向データフロー
- props が滝のように流れ落ちる
- 関数型プログラミングと相性がいい
- 数学的な純粋性
- 関数型プログラミングと相性がいい
- props が滝のように流れ落ちる
- フォーム
- 「state のリフトアップ」
- 親コンポーネントが state を持つ
- state 変更関数を作る
- 子コンポーネントに props として渡す
- state 変更関数を作る
- コンポーネントのメンタルモデル
- ReactElement で仮想DOMをつくる
- パラメータ設定できるロジックブロックの化身
- コンポーネント
- JSの関数
- props が引数、戻り値は ReactElements
- state を持てる点が関数と違う
- props と state が同じなら変わらない
- どちらかが変わると戻り値も変わる
- レンダリングが再実行される
- props と state だけを見ていればいい
- JSの関数
- ReactElement で仮想DOMをつくる
- props が大事
- state は副作用がある
- 純粋関数にしたい
- 引数が同じなら同じ戻り値を返す関数
- 純粋関数にしたい
- 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 の型合成が面倒
- HOCへの批判
- ラッパー地獄
- ReactElement を返す関数を props として受け取って自身のレンダリングに利用するコンポーネント
-
Hooks
- HOCやrender props は設計パターンだった
- Hooksは機能
- 解決したこと
- ロジック追加ごとにコンポーネントの階層が深くなる問題
- 外に状態やロジックを持つ
- 状態を伴った再利用可能なロジックを追加できる
- ほぼ関数コンポーネントだけで作れるようになった
- クラスコンポーネントの必要がほぼなくなる
- 機能ごとに副作用処理をまとめられる
- ストラングラーパターン
- 書き換える必要はない
- クラスコンポーネントの必要がほぼなくなる
- ロジック追加ごとにコンポーネントの階層が深くなる問題
- HOCやrender props は設計パターンだった
-
-
useState
- 初期値をnullにするには?
useState<User | null>(null)
- 前の値を使うときはアローで書く
setCount(c => c + 1)
- ❌
setCount(count + 1)
- if の中に書いてはいけない
- 初期値をnullにするには?
- 副作用とは
- side-effect
- コンポーネントの状態を変化させ、それ以降の出力を変えてしまう処理
-
y = f(x)
でf(1) = 2
がf(1) = 5
になる- propsが同じでも出力内容が変わる
- レンダリングに同期させて実行するための
Hooks API
- Effect Hook
- レンダリングに同期させて実行するための
- propsが同じでも出力内容が変わる
-
- コンポーネントの状態を変化させ、それ以降の出力を変えてしまう処理
- side-effect
const SampleComponent: FC = () => {
const [data, setData] = useState(null);
...
useEffect(() => {
doSomething();
return () => clearSomething();
}, [someDeps]);
...
};
-
useEffect
-
clearSomething()
で外部の購読処理を解除する -
someDeps
は依存配列- 省略すると?
- レンダリングごとに第一引数の関数が実行される
- 空配列を渡すと?
- 初回レンダリング時のみ第一引数の関数が実行される
- 省略すると?
- 初期値レンダリングの後、副作用反映後の内容で再レンダリングされる
- 副作用処理がコンポーネント表示をブロックしない
- とりあえず何か表示されている
- 処理中を伝える
- レイアウト崩れを防ぐ
- とりあえず何か表示されている
-
useLayoutEffect
- 副作用処理が軽いもの
- DOM要素・ブラウザ幅を取得してレンダリングに利用する
- あくまで
useEffect
を使う
- 副作用処理が軽いもの
- クラスコンポーネントとの違い
- クラス
- マウントでインスタンス生成
- アンマウントまで生き続ける
- props や state は常に最新
- メンバー変数
- props や state は常に最新
- 関数
- レンダリングのたびに実行されては破棄される
- props や state は外から注入される
- レンダリングのたびに実行されては破棄される
- クラス
- 機能凝集度が高い
- 購読開始・切り替え・解除が
useEffect
内にまとめられる- 可読性が高い
- 再利用しやすい
- 「この処理はこの条件の時に実行されるべき」
- 購読開始・切り替え・解除が
- 副作用処理がコンポーネント表示をブロックしない
-
- メモ化
- 必要なときだけ計算して、結果をメモしておく
- パフォーマンス最適化
- 再レンダリングされるたびに実行されるのを防ぐ
- パフォーマンス最適化
-
useCallback
- 関数定義そのものをメモ化する
-
useRef
- 本来はリアルDOMと繋げるもの
- 再レンダリングを伴わず何らかのデータを関数コンポーネントに保存したいとき使う
- 必要なときだけ計算して、結果をメモしておく
const timerId = useRef<NodeJS.Timeout>();
...
if (timerId.current) clearIntervall(timerID.current);
-
Custom Hook
-
use
をつけて切り出す
-