1. kkeethのエンジニア雑談チャンネル
  2. No.116 「最速攻略! Reactの..
2022-10-23 29:27

No.116 「最速攻略! Reactの `use` RFC」をダラダラ読む回

はい.第116回は


最速攻略! Reactの `use` RFC
https://zenn.dev/uhyo/articles/react-use-rfc


を読みました💁

いや〜,さすがは uhyo さんの一言で,深い考察,わかりやすい解説,キッチリとした言語化!もう惚れ惚れするような記事でした.こういう技術記事を書きたいものだ… また,今後の React の進化も楽しみだなと感じる RFC だったとも思います.より開発者フレンドリーなライブラリに進化するようです. use フックもぜひ実装されてほしいなと私も思います!


ではでは(=゚ω゚)ノ



See Privacy Policy at https://art19.com/privacy and California Privacy Notice at https://art19.com/privacy#do-not-sell-my-info.

00:04
10月19日、水曜日ですね。 遅刻は昨日もありました。
今朝からですね、僕デフォルトブラウザーが クロームだったんですけど、
もうクロームがどうにも重くてですね。 例えばノーションページ開くのに、
なんか1分ぐらいかかったので、 今朝サファリンに変えてみたらですね、
超絶高速で、もう一瞬で開くんですね。
まあ多分使ってた年数が全然違うのと、 キャッシュ回りとかいろんな設定だと思うんですけど、
とにかく超高速で、自分の時間の、 人生の時間をどんだけクロームに無駄にしたいな、
っていう感じがあるので、ちょっと今朝から、 そうですね、サファリにすごく感動していたっていう噂でした。
はい、すいません。おはようございます。 夢見のkeethこと桑原です。
では本日も朝から始めていきたいと思います。
今日はですね、昨日かな? 確かウフヨさんが書かれてた、
前に書かれた記事ですね。 最速攻略＀＀Reactの use RFCというところですね。
もうちょっと読んでいこうかなと思っています。
まあ一応名前だけは確かに聞いてたんですけど、 僕が気にしているRFCっていうか、
Reactの次のリリースって、僕はReactサーバー コンポーネンツの方ばっかりが、
僕はちょっと注目してたので、 その辺どうなるのかなって。
レイアウトRFCですね。 ReactとかNextも多分その辺カバーするって言ってたんですけど。
レイアウトRFCとReactサーバーコンポーネンツの方が 僕はちょっと気になってたんで、
so useRFCちょっと全然追ってなかったんですけど、
まあせっかく夢見さんが記事書いてくださったので、 読んでいこうかなと思っております。
では早速入っていきたいと思います。
おはようございます。
今日もタイトルの記事をダラダラ読んでいく感じですので、 ゆるく聞いていただければと思います。
では早速いきましょう。
みなさんこんにちは。
最近のReact界隈で話題になっているのは 次のRFCですというところで、
ファーストクラスサポート for promise and async await by acdlightのプロリクエストが出ています。
そこでこの記事では早速そのRFCを理解することを目指していこうと思っています。
ただしこのRFCはサスペンスに深く関わるものです。
サスペンスはReact18でもう正式リリースされていますけど、 この記事ではサスペンスは前提知識とさせていただきます。
もしまだサスペンスをよく知らないようであれば ぜひ次の記事で学習してください。
Reactのサスペンス対応非同期処理を手書きするハンズオンという ノーションのブックがあるのでそっちを見てみてください。
ちょっと僕これ知らなかったので後で手動かしてみようかなと思います。
それを置いといて、またRFCというのはあくまで Reactの新機能のアイディアを公開するものであり、
これが必ず実装されるとは限らないという点にご注意ください。
例えば過去にはユーズイベントというRCが注目を集めていましたが、
ありましたね、確かに。
ユーズイベントありましたけど結局、
なるほど、クローズされたんですね。
意見が集まった結果として、そのRFCは実装されずにクローズされました。
RFCが無駄だったというわけではなくて、
再度検討してよりアイディアがブラッシュアップされることになりますということで。
こういうコミュニティの議論ってすごく大事なことですよね。
別に仕事でもないし自分の時間を使っているんですけど、
03:00
こうやっていろんな意見があってより新しいアイテムとしてブラッシュアップされるというのは本当にいい話なので。
なのでクローズしたこと自体が別に無駄だとは思ってないですね。
というわけでいきましょう。
新しいユーズAPIです。
このRFCに大きく分けて2つの特徴があります。
1つはサーバーコンポーネンツに関係するもので、
もう1つはどんなコンポーネンツも使えるものだそうです。
現在の状況だと後者の方に興味がある人が多いのではないでしょうかということで、
今回はそちらを中心として説明します。
僕は前者の方に興味があります。
実際に開発現場の方は多分後者の方ですよね。
どんなコンポーネンツでも使えるようになるというのが多分大きいと思いますけど。
このRFCでは新しいユーズという関数が実装されます。
RFCの説明ではこれは特殊なフックであるというふうに一応されています。
使い方は次のようになります。
RFCから引用したソースコードが出てきていて、
これを音読するのはちょっとあれなんですけど、
一応適当なファンクションノートという関数があって、
引数にいくつか受け取ります。
constnote="use",という関数を実行してフェッチノートの何か適当なやつを実行すると。
その結果が返ってくる感じですね。
それをまたいつも通りJSXでレンダリングをしてという感じですね。
本当に他のユーズなんちゃら系と使い方はほぼほぼ一緒って感じですね。
その中のフェッチノートというフェッチャーメソッドとか、
フェッチノートオーサーみたいな回避であることがさせられるように、
ユーズに渡されるのは基本的にはプロミスですよねってことですね。
コードを見るとユーズにプロミスを渡すとその中身を取得できています。
およそユーズのシグネーチャーは次のようであると考えられます。
シグネーチャーはconstuse="genericst",でpromise="promiseT",で返ってくるの。
で、レスポンスもTになりますよねってことです。
こっちはタイプスクリプトの形でできたので、
ちょっと音読だと分かりづらいので皆さんも見てみてください。
つまり、awaitのようにプロミスから中身を取り出すのがユーズの役目ということですね。
プロミスに渡されたプロミスが未解決だった場合の挙動は従来と同じです。
つまりその場合はユーズの返り値を用意できないため、
コンポーネントなサスペンドが発生してその関数の実行は中断され、
プロミスが解決してから再実行されますと。
従来のサスペンスと異なる点というのも従来はリアクトは
投げられたプロミスが解決したら再度レンダリングを試みることのみをサポートしていて、
プロミスの中身を取り出すことは我々に任されていました。
それに加えてユーズではプロミスの中身を取り出すところまでやってくれるのが新しい点ですよと。
はーね。
従来はリアクトのサスペンス機構を生で使うのが難しく、
何らかのライブラリーを経営して使うのが主流でした。
ユーズの登場により簡単なケースからライブラリーを使わずに
プロミスを取り扱えるようになりますということでした。
そうねー、なるほどなるほど。
プロミスはとかく職人系になりがちな感は正直あるので、
これは嬉しいかもしれない。
特殊なフックというのが次のセクションですね。
06:01
RFCではユーズというのはフックの一種であるとされています。
しかしユーズは従来のフックと違うところがあります。
それは条件分岐内でも使用して良いということです。
上の例でもif文の中でユーズが使われているのが見て取れます。
リアクトにおけるフックのルールは次の2つに対別されました。
関数コンポーネントの中、および関数コンポーネントないから呼び出されるカスタムフックの中でしか使用できない。
もしくは常に同じ順序で同じ数だけ呼ばれなければならない。
条件分岐により呼んだり呼ばなかったりすることはできないということですね。
というのが大きく2つのルールでした。
ユーズはこの2つのルールのうち前者のみを制約として持ち、後者のルールは適用されないことになります。
なぜユーズに後者のルール、常に同じ順序で同じ数だけ呼ばなければならないというルールが適用されないのかというと、
そもそもなぜこのようなフックのルールが存在しているのかというのを考えれば理解できます。
まず前者のルール、関数コンポーネントの中でしか使用できないということですね。
前者のルールはフックはコンポーネントに属することから説明できます。
例えば、useStateはコンポーネントのステートを宣言するものです。
コンポーネントの外で使うとどのコンポーネントのステートを宣言しているか分からない。
また、useContextはコンポーネントがコンポーネントツリーのどこに存在するか分からないとコンテキストの値を取得できませんから、
からこれもコンポーネント属しています 確かで次に校舎のルールですけどフックが
コンポーネントの記憶領域にアクセス することから説明できます
ユーズステートがコンポーネント内に ステートを用意するのはもちろん
ユーズレフやユーズメモなどもコンポーネント 内の記憶領域を利用しています他にも
ユーズエフェクトもクリーンアップ関数が コンポーネント内の記憶領域に保存されて
いると考えられますはいでクラスコンポーネント 自体にディスとして自由にアクセスでき
た記憶領域が関数コンポーネントではフック の裏に隠されていると考えると
わかりやすいでしょうとああねなるほど でした
でフックの api の特徴というのはコンポーネント の記憶領域内のデータに名前を付け
ないということです代わりに何番目のフック 用の記憶領域なのかっていうのを頼りに
フックの記憶領域の読み書きが行われます この点については詳しい解説記事が
探せばあると思うのでここでは詳しい説明 は省略しますとで本題に戻るとなぜ
ユーズには校舎のルールが適用されないでしょうか それはコンポーネントないの記憶領域を
使用しないからであると考えられます ユーズは与えられたプロミスの中身を取り
出すだけなので実は記憶領域必要ありません ということですねはい一方で前者の制約は
必要ですなぜならプロミスがまだ解決しない 場合にコンポーネントをサスペナーさせる
必要があるからですああ確かにそうですね 以上のことを考えるとユーズは特殊な
フックというよりもフックの新しい分類を 立ち上げる存在であるというふうに
考えられますで従来のフックたちを記憶領域を 必要とするフックとして新たに記憶領域を
必要としないフックというまあ分類ができた イメージですわーとても分かりやすい
ですねさすがさすが6さんって感じ 両者に別々の名前つけても良いと思うん
ですがまあ用語を増やすとユーザー混乱する でしょうからそれは避けたのではないか
というふうに思われますまたユーズ以外に 今後記憶領域を必要としないフックが
09:03
出てくるかどうか不透明なのでそれを防ぐ ためにユーズという超汎用的なあの名前
つけたとも推測できます今回ユーズは特殊 なフックという立ち位置にしたのでしょう
というところです ここまでしっかり言語されると
なんかしすっと入ってきて 分かりやすいですねはい
ついてユーザー何を解決するのかという ところです以下の記事を読んだ方先ほど
紹介したやつですねはいリアクトの サスペンスを利用してコンポーネント
各方法を理解したはずですでこの記事を 読むと分かる通りコンポーネントの
サスペンドを有効に活用するためには コンポーネントの外部にデータを保存
することが必要でしたと 上記の記事の6章コンポーネントの
外部にデータをもとでデータの保存のために グローバルなキャッシュキーを用意する
必要があると説明しました実際にこれは まあ現在 swr やターンスタッククエリー
ですね元リアクトクエリーというライブラリー ですというものに使われている
アプローチだそうですねああそういう アプローチグローバルなキャッシュキーを
用意するようなプローチしたんですね またプロミスをスローすると
コンポーネントは必ずサスペンドするので コンポーネントはサスペンドさせるか
どうかの判断をするためには読み込み完了 したかどうかというフラグを別途持って
おくことが必要ですと上記の記事の7章 レンダーアズユーフェッチパターンの
実装においてもプロミスと読み込み完了 フラグをセットにしたローダブルという
データをデータ構造を紹介しました 以上のことはプロミスが一級市民で
なかったという説明することできます まあそうですねJavaScript界隈において
プロミスは一級市民とは言えないでしょうね でプロミスはJavaScriptの言語
仕様においては非同期処理そのものを表す 汎用性の高いオブジェクトではあります
しかしリアクトのサスペンスの文脈においては 今のところコンポーネントを
サスペンドさせる道具という程度の位置づけです そのためアプリケーションの
ロジックにおいて便利に使われるプロミスを コンポーネントツールに持ち込む際には
useSWRとかuseQueryあるいはローダブルといった 中間層が必要になっていました
確かにで今回のRFCで導入されるユーズっていう のはこのギャップを埋めてくれます
リアクトコンポーネント内から直接プロミスの 中身を取り出せるようにすることで
リアクトコンポーネントの内においても プロミスを非同期処理そのものとして
取り扱うことができます 筆者は中間層を除去することによって
リアクトとプロミスの親和性が向上し リアクトにおける非同期処理の
取り扱いがよりエンジニアにとって 分かりやすくなると期待しています
でRFCのタイトルもよく見ると First Class Support for Promise Under
Async Awaitとなっています これは上記で説明したように
リアクトがプロミスを直接サポートする っていうことを表してるんでしょうと
そうですねAsync Awaitがどう変わってくるか っていうのはもう少し後で
説明してくれるんですね はいということでした
で続いてユーズはキャッシュと 組み合わせようというところです
RFCには次のような注意が書かれています これが意味するところについて
説明しますキャビートと書いてあって データリクエストMust be
Cached Between Replaysって言ってますね 先ほどのソースコード例を
引用されてましてここで使われている フェッチノードの実装がこんな
感じだったとするとこのコンポーネント は再レンダリングのために再び
12:03
フェッチが発火してしまうことになります フェッチノードっていうのを最初に
ユーズで実行してそのノードを受け取って それをJSXでカートレンダリング
してるんですけど もう一個if分岐の中でフェッチノード
オーサーっていう別の著者のほうの データを取ってくるとしましょうね
それもユーズの中でオーサーで受け取って そのオーサーをまたJSXで
返してあげるって感じですね そんな実装になってますけど
このコンポーネントは再レンダリングのために 再びフェッチが発火
しまうっていうような感じになってます 例えばフェッチにするときの
IDって言うんですね IDそのままで別の値ですね
ShouldIncludeOtherっていうのが中に 一応あるんですけどこれはやっぱ
音読になるのでちょっと理解難しい かもしれないので後ほどソース
コード見てみてください このShouldIncludeOtherっていうのが
変更した場合もフェッチノード IDってのはやっぱり実行されます
要は中で持っていればデータが 変わってしまえば結局フェッチ
もっかい発火しまうよねってことですね それどころかユーズはサスペンド
後に関数コンポーネントを再実行 するので一回のレンダリング
でも複数回発火する可能性がある ようと言ってます
はー確かにね このようにユーズに対してプロミス
を渡すという性質上うまくやらない と無駄な非同期処理が発生します
例えば同じIDに対するリクエスト は一定時間キャッシュしておく
というような何らかのキャッシュ 機構は未だに必要だということです
それなら一回だけフェッチノード を呼ぶように制約すればいいじゃん
っていうふうに思われそうですけど Reactの思想的にはコンポーネント
は極力適当にしてキャッシュを使って パフォーマンスを確保してほしい
ようです はーそうなんや
またコンポーネントの最初のレンダリング でサスペンドする場合を考えると
どの日コンポーネントの外部に データを持つ必要があるため面倒
くささはそこまで減っていません キャッシュをわざわざ導入する
のは面倒くさいように思いますが 現在のところサスペンスはそもそも
Use Queryなどサードパーティー のライブラリーと組み合わせて
使うことが多くその場合はこの ようなキャッシュ制御はもともと
ライブラリーが行ってくれています つまるところ非同期データの読み込み
に関する役割の分担というのは Useの登場前後で次のように変化
することになりますと言っています これは表がありまして縦に処理
出力Use前の分担Use後の分担ですね 横軸に非同期データの読み込み
と非同期データのキャッシュと コンポーネントをサスペンド
させるかどうかの制御と書いて いますね
一個一個見ていきましょうか 非同期データの読み込みの場合
は出力はプロミスUse前の分担は ユーザーのコードUse後の分担
もユーザーのコードですと非同期 データのキャッシュの方は出力
はプロミスですけどUse前の分担 はサードパーティーUse Queryなど
Use後の分担もサードパーティー ですと最後コンポーネントをサスペンド
させるかどうかの制御ですけど 出力はプロミスをスローする
もしくはしないでUse前の分担は サードパーティーでUse後の分担
はリアクト本体になるというところ ですね
つまり非同期データの読み込み 中にコンポーネントをサスペンド
するという一連の処理を1から3に 分けて分類するとUseの登場によって
サードパーティーのライブラリー からリアクト本体に移管された
15:00
ということですね
そうなるとUse SWRやUse Queryを使用 する顕著な理由として残るのは
キャッシュの制御をしてくれる 点というだけになりますね
確かにそうですね
またコンポーネントをサスペンド させるかどうかの制御をしてもらう
という責務をUse SWRやUse Queryから 除去したとするとこれらがフック
である理由はもはやなくなります
うわ確かに
ライブラリー側からするとプロミス をスローするというリアクト特有
のプロトコルに縛られる必要が なくなり単なるプロミスを出力
すればよくなります
これによってライブラリー側は もはやリアクト専用のAPIを提供
する必要がなくなりライブラリー 側にもメリットがあります
そうね
このようにライブラリーとリアクト 本体の間のインターフェースが
エタンナルプロミスになったという のも目覚ましい進化だと言えます
これもプロミスの一級市民化の 一環です
さらに言えば実はRFCではUseと相性 の良いキャッシュAPIのRFCも出ている
ということが予告されています
つまり上の表の2もリアクト本体 に移管される可能性があります
2というのは非同期データのキャッシュ なことですね
ここもリアクト本体に移管される 可能性があるというふうに言って
いますね
そうなると非同期データのフェッチング のライブラリーは不要になるか
あるいはキャッシュ戦略を提供 する薄いライブラリーとして
残るという未来が予想できます
その方向性に別途してリアクト アプリケーションを設計するのも
悪くない選択でしょうと
これは面白いご意見ですね
まあそのUseのこのRFCが本当に 実装されるかどうかっていうので
一応戦略的にどうするかは意思決定 したいと思いますけど
確かにありっちゃありですね
来る可能性があるんだったら先に そういう構成にしておくのは
全然ありだと思いますね
いや面白いな
UseSRとかを使わなくて良くなる 未来が来るとは思ってなかった
のでちょっと驚きですね
続いてUseのためのリアクトコア の変化というところですね
この記事意外と長いんでこの朝 活用に終わらない可能性はちょっと
ありますけど
頑張ります
Useはただ新しいAPIが実装される というわけだけではなくて
それに対応するためにリアクト のコアにも変化が加えられます
UseのRFCではリアクトがプロミス の中身の読み取りを担当する
ということを思い出してください
つまりキャッシュの機構が入った としても非同期処理の結果はプロミス
で良いということになります
すでにキャッシュされていた場合 はすでに解決されたプロミスが
返されます
このようにキャッシュの有無に関 わらずプロミスが結果となるという
のはインターフェースの完結化 に有効であり
JavaScriptにおいてAsync関数が常に プロミスを返すという事情にも
適合しJavaScriptフレンドリーですね
それもそうですね
ところが一つ問題があります
それはJavaScriptにおいてはプロミス から同期的に値を読み出す方法が
存在しないということ確かにそうですね
すでに解決済みのプロミスだとして も必ず非同期処理を読み出す必要
があります
その通り
例えば上の例で一つ例が出てまして
const promise="promise.resolveでなんか 中っていう文字列が返ってくる
promise.thenでバリューを受け取って
console.logでバリューをとりあえず 出力すると
でそれを終わった後のconsole.log でピカっていうのを出してみる
なるほどですね
という感じの処理がもう書いて あった場合
上の例ではピカと中の順に出力 順番に出力されます
18:03
そりゃそうですね
プロミスの処理よりも先に同期 的な処理のconsole.logピカが先に
出力されますと
そうね
でこのようにすでに解決済みの プロミスだとしても同期的な処理
の方が読み出しより先に処理されて しまうよねって話です
それはそうですね
一方でリアクトレンダリングは 同期処理です
これは関数コンポーネントがasync関数 ではなく普通の関数であることから
わかります
そうね
これが意味するところは
すでに解決済みのプロミスだとして も
リアクトコンポーネントレンダリング 中にプロミスの中身を取得する
ことは不可能だということです
従来のリアクトではこれに対して 読み込み完了しているならばプロミス
をスローしないという形で対処 していましたが
これはプロミスの読み込み完了 状態はプロミスと別に持っている
必要があるので
プロミスが一級市民とは言えません でした
はい
でここからUseの魔法というところ に入ります
前の例を思い返すと同期的に実行 されるコンポーネントの中でUse
を使うと
プロミスの中身が同期的に読み 出せるというAPIになっていました
普通に考えるとこれは不可能なので この魔法のような挙動を実現する
ために
リアクトが裏で何かやってくれて いるということになりますと
もちろんUseもサスペンスをベース としているので
プロミスが読み込み中だったとき はコンポーネントをサスペンド
されます
そのプロミスをスローしたとき と同等の挙動になりますよということ
ですね
その場合プロミスが解決したとき は再度レンダリングが行われます
でここで問題となるのは
リクエストが既にキャッチされた 場合においてUseに渡されるのは
すぐに解決されるプロミスである ということです
つまりリアクトはUseに渡された プロミスがすぐに解決されるか
どうかっていうのを判別してサスペンド するかどうかを判断する必要があります
そうね
でこの判断機構がUseに伴ってリアクト コアに新たに実装される機能である
と考えられます
そしてこれがどのように行われる かについては実はRFCをよく読む
と書いてありますと
ちょっと英文長いので端折ります
つまりプロミスがすぐに解決される ということをレンダリング後に
マイクロタスク級が全部消化される までに解決されるとして定義し
この場合はコンポーネントのレンダリング が成功したと判断しサスペンド
を省略します
ただしプロミスの中身が判明して からコンポーネントの再レンダリング
をするという機構は依然として 必要となるので1回のレンダリング
で関数コンポーネントが複数回 見出されるのは従来と変わりません
それもそう思ってました
で従来のサスペンドにおけるレンダリング サスペンド発生完了したら再レンダリング
というフローは変わらないまま これが一瞬で終了したらサスペンド
扱いにならずレンダリング成功 と見なされるようになると理解
しましょう
これによって従来は完全に同期 的だったレンダリングという処理
がマイクロタスクレベルの遅延 であれば待ってくれるという意味
で非同期的な処理になったと考える ことができますこの点が今回の
RFCの本質的なポイントでしょう
割となんか大きい進化だなこう だって聞くと
ではUseの裏側と記憶領域の話ですね
この記事の前半でUseはコンポーネント 内の記憶領域を必要としない
ので条件分岐の中で呼び出すことが できると説明しました
しかしUseが記憶領域を全く使用 しないというわけではありません
21:00
Useに渡されたプロミスの結果は どこかに保存されており再レンダリング
時はUseはそちらの記憶領域から 結果を読み込んで返すことによって
Useにプロミスを渡すとその中身 が取り出されるという挙動を実現
しています
そうなると結局記憶領域が必要 になりますね
しかしここで使われる記憶領域 はコンポーネント単位ではなく
レンダリング単位です
つまりUse用の記憶領域はレンダリング 時に確保されそのレンダリング
が成功利に完了すれば記憶領域 は破棄されます
そしてUseも普通の服と同様に何番 目の読み出しに依存しても記憶領域
からデータを読み出します
それにも関わらずUseを条件分岐 の中で使用できるのはレンダリング
の最中に条件分岐の結果が変わる ことはないという仮定を設けている
からです
レンダリングの最中に分岐の結果 が変わらない
そうそうそれは確かにそうかもしれない
Reactコンポーネントはもともと 純粋性プロプスやステートが同じ
ならば同じ結果になるということ が必要とされています
これは確かにそうね
この性質からプロプスやステート が同じならばコンポーネントない
の計算も同じようになる行われる はずで
if分の分岐が前回と異なる方向 に進むことはないだろうから
分岐の中でUseを使われても大丈夫 だということです
一個だけここに注意書きがあって 関数の結果だけでなく実行過程
にまで制約がかかるという点が やや特殊で
純粋性の定義によっては納得できない かもしれません
副作用がないという意味での純粋 性であればたぶん実行過程も同じ
になりそうですというのは一応 法則にしていました
だいぶ前に出てきた例をもう一 回再掲されていまして
if分の中を取るか取るかという のはプロプスのみに依存している
のでプロプスが変わらなければ Useの実行回数や順序も変わらない
はずですこの過程によって条件 分岐の中でUseを使っても問題ない
のですというふうに言っています 逆に言えば純粋性を崩す形で条件
分岐の中でUseを使うのはやはり 不可能だと言っています
はぁはぁはぁ例えば次のように すると動かないはずですと
次のようにっていうのがifのます. ランダムでif分岐をする場合ですね
その中でUseを使うのはやはりダメ でしょうと言っています
適当性が保たれないような場合 は無理ですよと言うですねif分
の中で非純粋なリアクトコンポーネント を書く人は今時いないと思います
が確かにねこのようにリアクト の新しいAPIがどんどん純粋性
の上に乗っかっていきます純粋 なコンポーネントを書く習慣を
大事にしましょうとこの一言本当 ありがたいなと思いますね
ちなみにコンポーネント単位の 記憶領域はコンポーネントが初回
レンダリングときにサスペンド してしまった場合は破棄されます
これによりUseのような機能を 現在のリアクトの機能を使って
再現するのが難しくなっています
Useでは実行されると割と破壊 的な感じがするのでちゃんと作り
直さないといけない可能性がある のか
Useはコンポーネント単位ではなく レンダリング単位の記憶領域
という概念を導入してこれを克服 しているんですけどこの点がわ
ざわざリアクトコアにUseを導入 する理由となります
あってことは大丈夫かなUseにより プロミスを返す側でキャッシュ
が依然として必要になるのは既に 説明した通りですがプロミス
の状態をトラッキングする処理 をコンポーネントと外部で行う
24:00
必要がなくなるのですというの が何やかんやメリットということ
ですね
余談ですUseの他の用法ですUse はコンポーネント単位の記憶
領域を使用しないという点で従来 のフックとは異なると説明しました
実は皆さんが普段よく使う既存 のフックの中にもコンポーネント
単位の記憶領域を使用しないもの が紛れています
そうそれはUseコンテキストですね 本質的にはUseコンテキストは記憶
領域を使用しないため条件分岐 の中で使ったりしたら別に問題
なかったのですがフックという 統一された機構の上に乗ったために
Useコンテキストにも条件分岐の中で 使えないというルールが適用されて
いたのです
ということでRFCではUseに対する 将来的な拡張としてUseコンテキスト
とすることでUseコンテキストと 同様にコンテキストの中身を取り
出せるようになるかもしれない と述べられています
もちろんUseコンテキストはUseコンテキスト とは異なり条件分岐の中で使用
可能になります
Useコンテキストについてはたまたま Useコンテキストとして違和感のない
APIであるためUseに統合されそう ですがそれ以外に記憶領域が必要
ないフックが現れたときにUseに 続く第2の条件分岐の中でも使える
フックとなるかどうかは不透明 です
わざわざUseという特別な名前を ここで持ち出したとなればその
ような方向には進まないそうに 思われますけどということだそうです
続いてサーバーサイドエーシング コンポーネントだそうです
ここでUseを離れて次の話題に移り ます同じRFCではサーバーコンポーネント
ではコンポーネントをエーシング 関数にできるということも提案
されていますサーバーコンポーネント ではコンポーネントをエーシング
関数にできる
それはそうか
軽く復習しておくとReactサーバー コンポーネントではコンポーネント
がサーバーサイド用とクライアント 用に分類されて両者のレンダリング
結果を組み合わせることでReact アプリケーション全体のレンダリング
が完成するという構成になります Reactサーバーコンポーネントはまだ
正式リリースされていません
このRFCではサーバー側のコンポーネント をエーシングで書けるとされています
エーシング関数であるということ はプロミスの中身を得るために
Useではなく標準のawaitを使える ということです
サーバーコンポーネントの主要な ニュースケースとしてデータの
取得がありますからこれは相性 がいいと思います
この機能の導入によりコンポーネント がプロミスを扱うベストプラクティス
というのがサーバーサイドawait とクライアントサイドuseで異なる
ことになりますが
エーシングawaitの導入はそのデメリット を上回るメリットがあると判断された
ことからこのRFCに至りました
詳しい理由の説明はRFCにあります から気になる方は読んでみましょう
ちなみにRFCを読む限りエーシング コンポーネントが介したプロミス
は普通に解決されるまで待たれ ます
サスペンドとかそういうややこしい 概念はありません
その裏返しとしてエーシングコンポーネント ではhookが使えません
はっはっはっはそれはそうだよね
hookが出る前の関数コンポーネント のような味わいです
これについてはそもそもサーバー コンポーネントはステートレース
な計算をユースケースとしており ユーズステートやユーズエフェクト
などはもともとサーバーコンポーネント としては使えなかったので大した
問題ではないですよと
RFCでも言及されていますがエーシング コンポーネントとユーズIDを組み合わせ
27:01
られるのがちょっと不便な程度 だと思います
リアクトではFAQとしてクライアント サイドでもエーシングコンポーネント
をサポートしないのかという質問 があり技術的には可能だけど利用
に当たって注意すべき点が多く なってしまうので推奨はしない
という旨の説明されています
こちらも詳しくRFC読んでみましょう と使いはするけど自分で考えて
いないって感じですねこれは
まとめですこの記事ではリアクト の新しいRFCに記述されたユーズ
APIについて説明しました
ユーズを使う場合従来リアクト コンポーネントで非同期処理を
扱う際に必要だったプロミスを スローするというプロトコルを
リアクト内部に隠蔽することが できます
それに伴ってリアクトとサーバー サードパーティーライブラリー
の間のインターフェースが単なる プロミスの受け渡しになります
リアクトを使うエンジニアにとって は慣れ親しんだプロミスをリアクト
が直接サポートしてくれるのが 嬉しいしサスペンスを取り扱う
際にライブラリーを返せなくて 良いケースが増えるのも魅力的
です
一方ライブラリー側にとっても リアクト特有のプロトコルをわざわざ
サポートする必要がなく責務が 単純になるという利点があります
リアクトはこれまでサードパーティー ライブラリーと強調しながら何を
リアクトのコアに導入すべきか 慎重に検討してきました
今回のRFCもその流れにのっとり サードパーティーライブラリー
の負担を軽減してくれるものと なっています
その点で今回もリアクトらしい RFCだと言えるでしょう
筆者としてはぜひ導入されてほしい と思っています
好評に次続編ができました
なんでコンポーネントに副作用 があんだよ
教えはどうなってんだよ教えは っていう記事があるので
これは明日読もうと思います
というわけで今日の朝勝は こちらに以上したいと思います
うひょさんさすがでしたね めちゃくちゃ分かりやすかったし
すごくしっくりきたし ストーンと腹落ちするような
言語化されてたので ただただ拍手喝采な感じで
僕は読んでました 皆さんいかがだったでしょうかね
一応ソースコードは見ながら読んだ ほうが分かりやすいと思うので
皆さんのほうでまた改めて 読んでいただければと思いますし
僕もユーズ関数これかなり未来を 感じましたので
これはぜひ実装されてほしいな と思います
単なるプロミスのやりとりだけで 済むっていうのは
かなり嬉しくなるんで やっぱり物事はシンプルに
でもちゃんとやりたいことができる っていう
完全にこれは進化ですね なのでぜひ導入してほしいな
と思いました というわけでちょっと時間オーバー
したんですけど こちらで以上にしたいと思います
今日も多くの方たくさん参加いただき ありがとうございました
朝9時早い時頃から 本当に嬉しく思います
では今日中日ですね 今日も一日頑張っていけたらな
と思います では終了します
お疲れ様でした
29:27

コメント

スクロール