LoginSignup
1
0

SWRの楽観的更新ができない

Posted at

SWRを扱う上で躓いたところを共有し誰かの参考になればと思い、記事にしました。
SWRの使い方の記事ではなく、SWRを知っている前提の内容です。
公式 https://swr.vercel.app/ja

やりたいこと

楽観的UI更新(optimistic update)

楽観的更新とは、ユーザーが行った操作をサーバーからのレスポンスを待たずにUIに反映する手法のことです。
公式のソースコードはこのようになっています。

optimistic-updates

import useSWR, { useSWRConfig } from 'swr'  

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

  return (
    <div>
      <h1>My name is {data.name}.</h1>
      <button onClick={async () => {
        const newName = data.name.toUpperCase()
        const user = { ...data, name: newName }
        const options = {
          optimisticData: user,
          rollbackOnError(error) {
            // タイムアウトの AbortError だった場合はロールバックしません
            return error.name !== 'AbortError'
          },
        }  

        // ローカルのデータを即座に更新します
        // データを更新するためにリクエストを送信します
        // ローカルデータが正しいことを保証するために再検証 (再フェッチ) を発行します
        mutate('/api/user', updateFn(user), options);
      }}>Uppercase my name!</button>
    </div>
  )
}

ソースコード下部mutate('/api/user', updateFn(user), options) updateFn(user)
このソースコードにはないですがPromiseか非同期関数であり、更新後のデータを返します。
サーバからのレスポンスを待たずに<h1>My name is {data.name}.</h1>のdataをoptimisticDataの値で更新しています。

躓いたところ

optimisticDataの値でUIが更新されない。

結論

updateFn(user)の戻り値は、「指定されたキーのデータの型」と一致している必要があるようです。
この場合mutateのkeyは'/api/user'で、 const { data } = useSWR('/api/user', fetcher)のdataの型と一致している必要があります。
※私の場合はいいね機能を実装していて、dataはユーザ情報を持つ型でした。いいね更新APIの戻り値はPromise<boolean>としていたためうまくいきませんでした。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0