Closed4

memo @240217*

nakamotonakamoto

https://react.dev/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024
React LabsReactの研究を行ってるところ。

• useMemo, useCallback, memo → React Compiler
• forwardRef → ref is a prop
• React.lazy → RSC, promise-as-child
• useContext → use(Context)
• throw promise → use(promise)
• <Context.Provider> → <Context>

useMemo useCallback memoはメモ化(キャッシュのようなもの。一度行った計算をもう一度再計算させないようにする)するためのAPIuseMemoは変数useCallbackは関数を再利用する。memoはコンポーネント自体をメモ化する。それら3つはReact Compilerに置き換わる。React CompilerReactを最適化するコンパイラ。今までReactは再レンダリングが多いというネックがあったけどもそもそもReactはデフォルトでとても高速だから無駄な再レンダリングが行われても影響しないほど。けどそこが他のライブラリからするとReactよりも優れてるポイントであってそれを抑えるための方法としてそれらのAPIはあったけどそれらを適切に使用するのとても難しかった。ただReact Compilerによってその懸念はもう無くなる。我々の書いてるReactのコードはもともとコンパイルされてるし、そのお陰でブラウザでもサーバー側でも動くけども公式から提供されるこのReact Compilerによってそれを通すことによってuseMemo useCallback memoを使わなくとも自動的に最適化してくれる。

コンパイラはプログラミングにおいて非常に重要であり基本的にコンパイラを通すことによって最適化の恩恵も受けられるしバグも事前に減らせる。JSとTSでもJSはブラウザでそのまま動かせるけどもTSはコンパイルしてJSにして動かしてるし玄人が好んで使ってるのはやはりコンパイル型の言語。またReact Compilerを通したら我々が書いてるReactのコードのバッドなところを指摘してくれる。今もReactStrictModeによって指摘してくれるけどコンパイラレベルとなるとよりそれが厳格になる。

nakamotonakamoto

forwardRefはめっちゃ難しいしライブラリの開発者からすると必須のAPIであってもアプリの開発者からするとなくても開発できちゃう。内容としては自分が作ったコンポーネントやサードパーティーのコンポーネントを使うときにコンポーネント内部のDOM要素にrefを貼りたいようなとき使われる。それがforwardRefはいらなくなってrefはただのpropsとして扱えるようになる。

React.lazyはレイジーロードするためのもの。レイジーロードとはパフォーマンスを上げるためには重要であって全部の画像を一気に読み込もうとするととても時間かかるからページを最初に訪れたとき映らない画像はあとから読み込ませるテクニック(ヒーロー画像はレイジーローディングさせないけどその下の画像はレイジーローディングさせるみたいな)

イメージ戦略は3つあってまず一番最初に表示するものは超高速で表示する。次のイメージはブラーで表示する(Next.jsには組み込まれてる機能)。3つ目は特にスマホだとかなりスクロールしないと表示されないしレイジーローディングする。

ただ実際にはReact.lazyはどっちかというとif文の条件分岐とか使って、あとからコンポーネントを読み込ませたいようなときに使うことが多い。具体的にはユーザーがログインしてたらログイン用のページを出し、ログインしてなかったらログインしてない用のページを出すけども、そのときどっちのコンポーネントもインポートしてたらよろしくない。ユーザーがページに来てるときはログインしてる or してないの2択であるにも関わらず、どっちも読み込んでたら一つのコンポーネントが無駄になる。なのでそういう条件分岐のときはどっちのコンポーネントもReact.lazyを使ってインポートするかNext.jsならダイナミックインポートを使うかしてそのコンポーネントをあと読みさせる必要がある。これはバンドルサイズにものすごく影響する。React.lazyするだけでバンドルサイズが全く変わる。

ただ今回そのReact.lazyRSCに置いては不要になる。コンポーネントがRSCのランタイムの段階で既に決定されるためReact.lazyをしなくても自動的に最適化されるしそれはRSCのいいところ。React.lazyNext.jsApp Routerを使用する上ではいらないよねという話。

nakamotonakamoto

useContext → use(Context)

useという新しいhooksが出てuseContextを読み込むこともできるし
if文などの条件分岐にも使用できるためuseContextの上位互換となる。

throw promise → use(promise)

外部のデータフェッチするときもこれからはuseを使用する。

<Context.Provider> → <Context>

今まではContextにもProviderConsumerという2つの考え方があったけどもコンポーネントもProviderConsumerとあったけどもそれもConsumerというContextを読み取る方がuse(Context)となるしそしたらもうContextの中にProviderしかないよねという話。

このスクラップは2024/02/18にクローズされました