[[🗃️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()
}
}
```