[日本語訳]SWR ドキュメンテーション ミューテーション


追記: 2021年6月8日

SWR公式日本語訳ページが追加されたので、そちらをご覧ください

このページは Mutation – SWRの日本語訳です
SWR日本語訳全体についてはSWR 日本語訳をご覧ください

自動再検証

mutate(key) を呼び出すことにより、同じキーを持つすべてのSWRに再検証メッセージをグローバルにブロードキャストできます。

この例は、ユーザーが"ログアウト"ボタンをクリックしたときに、ログイン情報(<Profile />内など)を自動的に再取得する方法を示しています。


import useSWR, { mutate } from 'swr'

function App () {
  return (
    <div>
      <Profile />
      <button onClick={() => {
        // cookieの期限を設定します
        document.cookie = 'token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
        // このキーを使用しているすべてのSWRに再検証するよう伝えます
        mutate('/api/user')
      }}>
        Logout
      </button>
    </div>
  )
}

ミューテーションとPOSTリクエスト

多くの場合、データにローカルミューテーションを適用することは、変更をより速く感じさせるための良い方法です。データのリモートソースを待つ必要はありません。

mutate を使用すると、ローカルデータをプログラムで更新しながら、再検証して最終的に最新のデータに置き換えることができます。


import useSWR, { mutate } from 'swr'

function Profile () {
  const { data } = useSWR('/api/user', fetcher)

  return (
    <div>
      <h1>My name is {data.name}.</h1>
      <button onClick={async () => {
        const newName = data.name.toUpperCase()

        // ローカルデータをすぐに更新しますが、再検証はしません
        mutate('/api/user', { ...data, name: newName }, false)

        // APIにリクエストを送信してソースを更新します
        await requestUpdateUsername(newName)

        // 再検証(リフレッシュ)をトリガーしてローカルデータが正しいことを確認します
        mutate('/api/user')
      }}>Uppercase my name!</button>
    </div>
  )
}

上記の例のボタンをクリックすると、クライアントデータがローカルで更新され、POSTリクエストが送信されてリモートデータが変更され、最新のデータが取得されます(再検証(revalidation))。

ただし、多くのPOST APIは更新されたデータを直接返すだけなので、再度再検証する必要はありません。 "ローカルミューテート - リクエスト - アップデート "の使用法を示す例を次に示します。


mutate('/api/user', newUser, false)      // `false`を使用して再検証なしで`mutate`を使用します
mutate('/api/user', updateUser(newUser)) // `updateUser` はPromiseリクエストで更新されたドキュメントを返します

現在のデータに基づくミューテート

現在のデータに基づいてデータの一部を更新したい場合があります。

mutate を使用すると、現在キャッシュされている値がある場合はそれを受け取る非同期関数を渡して、更新されたドキュメントを返すことができます。


mutate('/api/todos', async todos => {
  // ID `1` の todo を更新して完了させましょう。
  // このAPIは更新後のデータを返します
  const updatedTodo = await fetch('/api/todos/1', {
    method: 'PATCH',
    body: JSON.stringify({ completed: true })
  })

  // リストをフィルターして、更新されたアイテムと一緒に返します
  const filteredTodos = todos.filter(todo => todo.id !== '1')
  return [...filteredTodos, updatedTodo]
})

ミューテートから返されたデータ

ほとんどの場合、キャッシュを更新するにはデータが必要です。 データは解決されるか、mutate に渡した promise または async 関数から返されます。

この関数は、更新されたドキュメントを返し、mutate が対応するキャッシュ値を更新できるようにします。 呼び出すたびに、なんらかのエラーが発生する可能性があります。


try {
  const user = await mutate('/api/user', updateUser(newUser))
} catch (error) {
  // ここでユーザー更新中のエラーを処理します
}

バウンドミューテート

useSWRによって返されるSWRオブジェクトには、SWRのキーが事前にバインドされているmutate()関数も含まれています。

機能的にはグローバル mutate 関数と同等ですが、key パラメーターは必要ありません。


import useSWR from 'swr'
function Profile () {
  const { data, mutate } = useSWR('/api/user', fetcher)
  return (
    <div>
      <h1>My name is {data.name}.</h1>
      <button onClick={async () => {
        const newName = data.name.toUpperCase()
        // APIにリクエストを送信してデータを更新します
        await requestUpdateUsername(newName)
        // すぐにローカルデータを更新して再検証(リフレッシュ)する
        // 注意: useSWRのmutateを使用する場合は、事前にバインドされているためキーは必要ありません。
        mutate({ ...data, name: newName })
      }}>Uppercase my name!</button>
    </div>
  )
}