[[🗃️SWR]]がわかって意なさすぎるので整理 - [ミューテーションと再検証 – SWR](https://swr.vercel.app/ja/docs/mutation) ## キャッシュの扱い - [[🗃️SWR]]は、`useSWR`、`useSWRMutation`を使った時に内部的にキャッシュデータを持つ - 第一引数をkeyとして[[🗃️キャッシュ]]を持つ ### `useSwr`と`useSwrMutation`の違い #### `useSWR` - 主に「読み取り」用途 - データをキャッシュして自動的に最新化してくれる - コンポーネントのマウント時に即フェッチされる ```tsx import useSWR from 'swr' // fetcher関数(APIからデータを取得する処理) const fetcher = (url: string) => fetch(url).then(res => res.json()) export default function Profile() { const { data, error, isLoading } = useSWR('/api/user', fetcher) if (isLoading) return <div>Loading...</div> if (error) return <div>Failed to load</div> return ( <div> <h1>{data.name}</h1> <p>{data.email}</p> </div> ) } ``` #### `useSWRMutation` - 「書き込み操作」用途(POST/PUT/DELETE など) - フック呼び出し時に自動で実行されず、トリガーを呼ぶときだけ実行 - `useSWRMutation` は初期レンダリング時には API 呼び出しをしない - `trigger(arg)` を呼んだ時だけ `/api/user` に POST ```tsx import useSWRMutation from 'swr/mutation' const updateUser = async (url: string, { arg }: { arg: { name: string } }) => { return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(arg), }).then(res => res.json()) } export default function UpdateProfile() { const { trigger, data, error, isMutating } = useSWRMutation('/api/user', updateUser) const onClick = () => { trigger({ name: 'New Name' }) } return ( <div> <button onClick={onClick} disabled={isMutating}> {isMutating ? 'Updating...' : 'Update Name'} </button> {error && <div>Failed</div>} {data && <div>Updated: {data.name}</div>} </div> ) } ``` ## キャッシュデータを更新・再検証する方法 ref: [ミューテーションと再検証 – SWR](https://swr.vercel.app/ja/docs/mutation#mutate-multiple-items) - [[🗃️mutate]]には種類がある ### 1. 楽観的更新(optimistic update) - 内部のキャッシュデータを更新してあげる形 ```tsx await mutate( '/api/user', async (current) => { await fetch('/api/user', { method: 'POST', body: JSON.stringify(user), }) // 手動で新しい値を返す(サーバーには依存しない) return { ...current, ...user } }, { revalidate: false } // サーバーを再フェッチしない ) ``` ### 2. [[🗃️mutate]]を使ってキャッシュを #### グローバルミューテート - 第一引数はフィルタ関数としても振る舞うことができる - 絞り込みにマッチするものだけが再検証の対象となる ```ts import { mutate } from 'swr' // キャッシュプロバイダをカスタマイズしている場合はフックから // { mutate } = useSWRConfig() mutate( key => typeof key === 'string' && key.startsWith('/api/item?id='), undefined, { revalidate: true } ) ``` #### バウンドミューテート - キーを使って、特定のキャッシュを指定してミューテートする ```tsx import useSWR from 'swr' function Profile () { const { data, mutate } = useSWR('/api/user', fetcher) const reload = () => { // useSwrの戻り値の場合はkey紐付け不要 mutate() } } ```