Render-as-You-Fetch
レンダーと同時にfetch
Fetch-on-render
既存の「useEffect内でfetchする」(Fetch-on-render)パターンではレンダリングが行われない限りfetchが走らない。つまり該当のコンポーネントに到達できなければfetchできないので必要なデータをすぐに用意することができないケースが生まれる(コンポーネント階層によってデータ取得同士に偽の依存関係が生まれて、同時に取れるデータを同時に取ることができない)
コンポーネントとデータのコロケーションという意味では明快で良いアプローチなのだけれど…
Fetch-then-render
「レンダリング前にfetchする」(Fetch-then-render)パターンでは必要なデータの取得を上位コンポーネントにまとめ、そこでPromise.allしてデータ取得ができてから下位のコンポーネントをレンダリングする。
Next.jsのgetInitialProps/getServerProps/getStaticPropsがイメージとして近そう コンポーネントのデータのコロケーションは、GraphQLのFragmentをコンポーネントごとに定義して実現する 上位のコンポーネントではFragmentを展開するというのを繰り返すことで、ページ単位の1つのクエリをボトムアップで生成する
データ取得同士の依存関係はなくなるが「このデータは後から表示してもいい」みたいなことを表現できない
Render-as-You-Fetch
必要なデータ取得を上位にまとめるのはFetch-then-renderと同じだが、Promise.allしないで個々のPromiseを取り回すイメージ。ただPromiseを取り回すコードは複雑になりがちなので、Suspenseを導入してコンポーネントのデータ依存と優先度を宣言的に表現できるようにする。 Relay Hooks(experimental)では@deferredディレクティブをクエリの一部に付与することでクエリを分割してこれを実現しているっぽい #要出典 Render-as-You-FetchパターンはFetch-then-renderパターンの派生/進化として考えることができるが、(Next.jsみたいな例外を除いて)コミュニティでは未だにFetch-on-renderパターンが広く使われていて、データ取得をまとめることの有用性があまりよく理解されていないという感覚がある。とはいえ、クエリを柔軟にまとめることができるGraphQLとは違って、RESTではデータ取得をまとめたとしてもリクエストの回数は変わらないのでそこまでFetch-then-renderに強みがなく、さらにFacebookではGraphQLが使われることが多いのでFetch-then-renderにパラダイムシフトという感覚がないのかもしれない(RelayのAPIに従ってクエリを合成していけば自動的に実現されるため) つまるところ、Render-as-You-Fetchパターンを実現するにはデータ取得をSuspenseが置かれている位置よりも上に引き上げる必要がある。実際どこにしたいのかと言うと、ページ遷移によって発生するデータ取得をuseTransitionで処理したいので、個々のページよりも上、ルートでやる必要がある。これを何とかして個々のコンポーネント単位に収めたいわけだが… とりあえずページ単位でのデータ取得までの分割は比較的簡単にできて、これはNext.jsを参考にページ定義単位でgetInitialPropsを書くようにすることで実現できると思う。