UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【React】React QueryとReact Location

@takepepeさんのスライドにあったReact Locationの話が気になったので、React Queryと合わせてどういうものか調べた

より速い WEB を目指す Next.js / nextjs-make-the-web-faster - Speaker Deck

React Query

react-query.tanstack.com

React Queryは、Reactアプリケーションのフェッチ、キャッシュ、同期、サーバーの状態更新を簡単にするライブラリ

特徴としては

  • フェッチしたデータをキャッシュする
  • キャッシュされたデータはどのコンポーネントからでも簡単に利用できる
  • フェッチの状態を返してくれる
  • リトライ
  • ポーリング

3つのコアコンセプト

  • Queries
    任意のPromiseベースのメソッド(GETおよびPOSTメソッドを含む)を使用して、サーバーからデータをフェッチ
  • Mutations
    データの作成/更新/削除、またはサーバーの副作用の実行する場合に使用する
  • Query Invalidation
    ユーザーが行った更新が原因でクエリのデータが古くなっていることがわかっている場合に、古いクエリを無効化して再フェッチするようにする

これらのコンセプトを実装した3つフックAPIを利用する

コードサンプル

import {
   useQuery,
   useMutation,
   useQueryClient,
   QueryClient,
   QueryClientProvider,
 } from 'react-query'
 import { getTodos, postTodo } from '../my-api'
 
 // Create a client
 const queryClient = new QueryClient()
 
 function App() {
   return (
     // Provide the client to your App
     <QueryClientProvider client={queryClient}>
       <Todos />
     </QueryClientProvider>
   )
 }
 
 function Todos() {
   // Access the client
   const queryClient = useQueryClient()
 
   // Queries
   const query = useQuery('todos', getTodos)
 
   // Mutations
   const mutation = useMutation(postTodo, {
     onSuccess: () => {
       // Invalidate and refetch
       queryClient.invalidateQueries('todos')
     },
   })
 
   return (
     <div>
       <ul>
         {query.data.map(todo => (
           <li key={todo.id}>{todo.title}</li>
         ))}
       </ul>
 
       <button
         onClick={() => {
           mutation.mutate({
             id: Date.now(),
             title: 'Do Laundry',
           })
         }}
       >
         Add Todo
       </button>
     </div>
   )
 }
 
 render(<App />, document.getElementById('root'))

このような感じでデータの取得、更新、再取得を行う

HTTP クライアントを選ばないので、すぐ導入できそう

React Location

React Queryの作者のTanner氏がルーターライブラリとして作ったもの、routerとprefetchingのインテグレーションを提供している

react-location.tanstack.com

React Locationはクライアント側のReactアプリケーション用のルーター

ドキュメントに書かれていた特徴

  • 非同期ルーティング
  • 深く統合されたSearchParams API
  • すべてのフック:ルーター、一致、ルート一致、プリロード
  • オプションのルートフィルタリング/ランキング
  • オプションのJSXルート定義
  • ルートローダーキャッシング用のパッケージ済みのシンプルなキャッシュ実装
  • 外部のキャッシュとストレージと簡単に統合できる(例:React Query、Apollo、SWR、RTKQuery)

この中でも、レンダリング前に非同期に依存関係のあるルートをすべて並行して事前にロードしておくことができる(クライアントサイドのキャッシュprefetch)機能が注目されている

サスペンドが利用できたとしても、サスペンドするだけでは「loading...」だらけになってしまう可能性があり、この機能はその問題を回避することができる

しかし、事前のデータ取得が無駄になるデメリットもあるのでそこは注意しながら使う必要がありそう

その他参考

https://zenn.dev/brachio_takumi/articles/20210226-react-query

https://qiita.com/uhyo/items/bbc22022fe846fd2b763