問題があります。非同期は難しいです。
単純な GET API、つまり searchText をパラメータとして受け取る検索があると想像してください。好みの http リクエスト ツールを使用して呼び出して Promise を取得すると、検索しているもののリストが解決されます。
React コンポーネントで呼び出すにはどうすればよいですか?
まず第一に、1 つのことに注目することが重要です。私が説明したものは次のようにモデル化できます。
result = await searchAPI(searchText);
ここで概念的な話をしましょう。 これは派生です。 searchText のバージョンごとに、異なる結果が得られます。しかし、ここにはいくつかの問題があります:
React で派生として呼び出すにはどうすればよいですか?
TanStack Query や SWR などのサードパーティ ライブラリを使用すると、問題が解決します。これらは、React コンポーネントで使用できるフックを提供し、状態とプロパティを受け取り、API が変更されたときに API に対して再計算 (再フェッチ) します。この例を見てください:
const { data: searchResult, loading } = useQuery({queryKey: [search, searchText],queryFn: getSearch,});
OK、非同期導出は解決しましたね?
そうではありません。
ところで、私は常にこれらのライブラリの 1 つだけを使用することをお勧めします。これらのライブラリは素晴らしく、より複雑なケース (再フェッチ、再試行、キャッシュ制御など) で時間を大幅に節約できますが、3 番目のものを当てにすることはできません。 -React の概念的な問題を解決するパーティー。
反応性の話に戻りますが、導出モデルで非同期ケースを処理する方法が必要です。 React はこの場合にプリミティブを提供するはずです。そうですね、バージョン 18 まではありませんでしたが、19 では違います。
React 19 では、use と呼ばれる新しいプリミティブが導入されています。はい、名前は少し混乱しますが、React の反応性モデルにおけるその役割は非常に重要です。これを使用すると、コンポーネントのレンダリング中に Promise を解決できます。 欠落している導出。
以前は、コンポーネントのレンダリング中にフェッチを呼び出す唯一の方法は、useEffect を使用して Promise を呼び出し、then 句で応答として返される値で状態を設定することでした。それはある意味うまくいきましたが、それを行うためにエフェクトを使用する際にはさまざまな問題がありました。
use プリミティブを使用すると、コンポーネントのレンダリング中に Promise を解決できるようになり、状態と props を使用して Promise を作成し、これらの Promise を解決して関数や JSX で使用できるようになります。
const useCountTotal = (count: number) => { const countTotalPromise = useMemo(() => genericPromise(count), [count]); const result = use(countTotalPromise); return result; } function AsyncDerivation({count}: { count: number}) { const result = useCountTotal(count); return ( <div>Total count is: {result}</div> ) }
これを書いている時点では、React 19 の最終リリースはまだありません。いくつかの注意点があり、おそらくこのプリミティブは将来、より多くの場所で動作するように進化するでしょう。
この原始的な使用法の 1 つの具体的な点は、サスペンスで使用する必要があるということですが、これには十分な理由があります。
await の概念的なアイデアは素晴らしいですが、React コンポーネントと結合すると欠陥があります。レンダリング中に await だけを使用することはできません。 React はコンポーネントを呼び出して JSX レスポンスを取得し、それをフローで使用して UI をレンダリングします。
await ですべてを停止できたとしても、React はそのコンポーネントの子にアクセスできず、ツリーの終わりまで作業を続行できません。レンダリング フローを停止し、UI が更新されずにフリーズするようにします。
それを解決するにはどうすればよいですか?
この記事で使用した 2 つの例を見てみましょう。 1 つ目は、レンダリング フローをブロックするのではなく、ロードなどのフラグを返すアプローチを採用しています。 Promise が解決されると、再レンダリングがスローされ、フラグが更新され、読み込みが false になり、データが応答データを受け取ります。
使用アプローチが異なります。実際には await プリミティブのように動作するため、コンポーネントのレンダリング フローは解決されるまでそこで停止します。
待て待て待て、問題があるって言ったよね?
そして、ここに救いのサスペンスが登場します。 use プリミティブを使用すると、それは Suspense コンポーネントにラップされ、レンダリング フローは使用の解決を待つのを停止し、ユーザーは UI 上にレンダリングされたフォールバックを取得します (通常は読み込みスピナーまたはスケルトンで、これを示すもの)そこに何かをロードしています)。
使用の約束が解決されると、レンダリングを続行し、それに応じて UI を更新します。 useEffect を使用する必要はありません。
use プリミティブは、Suspense を使用して非同期動作を扱うことを目的とするライブラリ作成者にとって非常に役立ちます。アプリ開発者にとっては、基本的な反応性モデルのもう 1 つのケースが修正され、単純なユースケースに最適です。 Promise をラップするため、http リクエストだけでなく、すべての非同期ケースや外部 API の使用にも適用され、エコシステムにリソースを追加できます。
以上がReact での非同期派生の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。