Slide 1

Slide 1 text

TanStackで効率的な ルーティングとデータ取得を実現 株式会社AI Shift・安井大晟(ytaisei) JSFes

Slide 2

Slide 2 text

自己紹介 ● 新卒1年目 ● Webフロントエンド ● React、TypeScript ● 去年のJSFesで初登壇 ● TSKaigi登壇

Slide 3

Slide 3 text

元々BtoB SaaSの開発を経験していた TanStackを紹介する経緯 ⇨ SEOや初期描画をtoCほど気にしなくて良い ⇨ INP(Interaction to Next Paint)が重要 技術選定どうする???

Slide 4

Slide 4 text

Frameworkを採用する場合の疑問 ● Next.jsなら1発アウトの事故が怖いので、 App Routerのキャッシュの扱いはどうする? ● Remixなら必然的にData Flowに沿った設計になるが、 全てのアプリケーションでFitする? TanStackを紹介する経緯

Slide 5

Slide 5 text

Frameworkを採用する場合の疑問 ● Next.jsなら1発アウトの事故が怖いので、 App Routerのキャッシュの扱いはどうする? ● Remixなら必然的にData Flowに沿った設計になるが、 全てのアプリケーションで Fitするか? Frameworkを採用すれば全て解決!!!ではない とはいえ、Frameworkを使わない場合はどうする??? TanStackを紹介する経緯

Slide 6

Slide 6 text

最適解はなくても、選択肢が欲しい!

Slide 7

Slide 7 text

Vite+Reactなら ● (少し前) React Router+Redux (最近だと)TanStack QueryやSWRも増えてきた Frameworkを使うなら ● Next.js ● Remix ● Remix SPA Mode Reactの選択肢を整理

Slide 8

Slide 8 text

● TanStack Router + Query Reactの選択肢を整理 新しい選択肢を提案したい! Vite+Reactなら ● (少し前) React Router+Redux (最近だと)TanStack QueryやSWRも増えてきた

Slide 9

Slide 9 text

TanStack Router について 02 04 01 03 Summary 05 Table of contents Request Waterfall を防ぐ設計 TanStack Query について React Router との比較

Slide 10

Slide 10 text

TanStack Router 01 File-Based・Type Safe・Code Splitting・Search Prams as State Management

Slide 11

Slide 11 text

● Fully Type Safe ● Built-in Loader Caching ● URL State Management 昨年のクリスマスに Versionが1系になった

Slide 12

Slide 12 text

File-Basedなルート生成 参考:https://tanstack.com/router/latest/docs/framework/react/guide/file-based-routing

Slide 13

Slide 13 text

Code-Basedで ルーティングを 実装する必要がない 各ルートごとに ● Route Component ● Error Component ● Pending Component ● データ取得のためのLoader を定義することができる

Slide 14

Slide 14 text

型安全でシンプルなルーティング 参考:https://tanstack.com/router/latest/docs/framework/react/guide/type-safety

Slide 15

Slide 15 text

ルーティングパスだけでなく、 Search Paramsなども型安全に扱える

Slide 16

Slide 16 text

バンドルサイズを軽減するCode Splitting 参考:https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting

Slide 17

Slide 17 text

lazy.tsxとroute.tsxに 分割するだけで Code Splittingしてくれる 各RouteごとにCode Splitting

Slide 18

Slide 18 text

route.tsx Critical Route lazy.tsx Non-Critical/Lazy Route 初回ロード時に読み込まれるコード 遅延して読み込まれるコード

Slide 19

Slide 19 text

Search Paramsによる状態管理 参考:https://tanstack.com/router/latest/docs/framework/react/guide/search-params

Slide 20

Slide 20 text

● 型がstring型に限定される ● 構造がFlatである ● Parameterの実装がPathと密結合している なぜURLSearchParamsを使わない?

Slide 21

Slide 21 text

● 型がstring型に限定される ⇨ 値に応じた型定義をしたい ● 構造がFlatである ⇨ ネストしたオブジェクトも扱いたい ● Parameterの実装がURL Pathと密結合している ⇨ URL Pathと分離して扱いたい なぜURLSearchParamsを使わない?

Slide 22

Slide 22 text

● Routeで型定義 ● Zodと組み合わせ可能 ● JSON-Firstで複雑な構造が扱える ● 型安全に扱える ● Validation可能 TanStack Routerを使うと

Slide 23

Slide 23 text

ユーザ目線 ● Search Paramsの状態を保ったままリンクを共有可能 開発者目線 ● JSON-Firstで複雑な構造が扱える上、Validationが可能なため、 1種の状態管理として採用することができる なぜSearch Paramsで状態管理する?

Slide 24

Slide 24 text

TanStack Routerを採用すると 型安全で効率的にルーティングができる

Slide 25

Slide 25 text

React Routerとの比較 02 参考:https://tanstack.com/router/latest/docs/framework/react/comparison

Slide 26

Slide 26 text

TanStack Router React Router File-Based Routing ✅ ✅* Nested / Layout Routes ✅ ✅ Typesafe Routes ✅ 🛑 TypeSafe Search Params (Validation) ✅ 🛑 Router Loaders ✅ ✅ Full-Stack API 🛑 ✅ * React RouterのドキュメントはCode Basedを前提にしている

Slide 27

Slide 27 text

TanStack Router React Router File-Based Routing ✅ ✅ Nested / Layout Routes ✅ ✅ Typesafe Routes ✅ 🛑 TypeSafe Search Params (Validation) ✅ 🛑 Router Loaders ✅ ✅ Full-Stack API 🛑 ✅ 大きな違い

Slide 28

Slide 28 text

React RouterのData Flow 参考:https://remix.run/blog/remix-data-flow

Slide 29

Slide 29 text

React RouterのCode React Routerにあって、TanStack Routerにないもの ActionsとForm APIの存在 Mutationは TanStack Routerの 責務ではない

Slide 30

Slide 30 text

TanStack RouterのData Flow

Slide 31

Slide 31 text

TanStack Routerだけでは Full-Stackにアプリケーションを 実装するのに不十分

Slide 32

Slide 32 text

そこで、TanStack Queryの出番!

Slide 33

Slide 33 text

TanStack Queryについて 03

Slide 34

Slide 34 text

TanStack Queryの基本

Slide 35

Slide 35 text

useQuery ● queryFnに登録したfetcher関数をレンダリング時に実行 ● 取得したデータをqueryKeyをkeyにしてキャッシュ

Slide 36

Slide 36 text

useMutation ● mutationFnに登録したactionをイ ベントをトリガーに発火 ● (データを最新にしたい場合は) invalidateQueriesで 更新したいキャッシュのqueryKey を指定 ⇨ 最新のデータに更新

Slide 37

Slide 37 text

TanStack Queryを採用すると サーバデータを効率的に管理できる

Slide 38

Slide 38 text

useQueryでデータ取得する課題 ● dataがundefinedの可能性がある ● 同一コンポーネント内で success, error, pending状態 の処理を実装

Slide 39

Slide 39 text

useSuspenseQueryを使うと Success状態 Error, Pending状態

Slide 40

Slide 40 text

useSuspenseQueryを使うと Success状態 Error, Pending状態 ● dataのundefinedを考慮しなくていい ● ErrorとPendingの処理を外に切り出せる

Slide 41

Slide 41 text

TanStack Routerと TanStack Queryを組み合わせる!

Slide 42

Slide 42 text

Suspenseも活用して実装をしたい!

Slide 43

Slide 43 text

ですが、TanStack RouterとuseSuspenseQueryを 組み合わせる際には注意が必要

Slide 44

Slide 44 text

Request Waterfallを防ぐ設計 04

Slide 45

Slide 45 text

例)2つのSuspense境界が存在する画面 一覧 詳細 (useSuspenseQuery) (useSuspenseQuery)

Slide 46

Slide 46 text

手元で実践

Slide 47

Slide 47 text

What is Request Waterfall??? 理想

Slide 48

Slide 48 text

useSuspenseQueryでデータ取得する場合 コンポーネントがレンダリングされる タイミングでデータ取得が開始され る ⇨ネストした子コンポーネントは親 のレンダリングが完了するまでデー タ取得が開始されない

Slide 49

Slide 49 text

fetch-on-render 一覧 詳細 1. |> getPostList() 2. |> getPostDetailById() Componentがレンダリングされる タイミングでfetchが開始する

Slide 50

Slide 50 text

TanStack Routerのloaderでデータ取得する場合 コンポーネントがレンダリングされる タイミングではすでにデータが用意 されている ⇨サーバデータのキャッシュを TanStack Queryで管理

Slide 51

Slide 51 text

render-as-you-fetch 一覧 詳細 1. |> getPostList() 1. |> getPostDetailById() Componentのレンダリングとは別に TanStack RouterのLoaderで まとめてfetchするため、 データ取得が並行で実行される

Slide 52

Slide 52 text

Request Waterfallを解消 実現!

Slide 53

Slide 53 text

Summary 05

Slide 54

Slide 54 text

1. TanStack Routerで効率的なルーティングが実現できる 2. TanStack Routerだけではサーバデータの状態を管理するのに不 十分なため、TanStack Queryと組み合わせる 3. Suspenseを活用する際にはTanStack RouterのLoaderで データ取得を行いRequest Waterfall問題に対応する

Slide 55

Slide 55 text

ご清聴ありがとうございました! https://twitter.com/ytaisei_ https://zenn.dev/taisei_13046