0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TanStack Query の invalidateQueries() や refetchQueries() がうまく動作しない時に確認すること

Posted at

きっかけ

useMutationしたタイミングで、invalidateQueriesを利用して、関連するクエリを再実行し状態を更新しようとしたところ、全然できず詰まってしまった。

このスレに救われたので、ここに載っていた間違い集をまとめておく。

確認した方が良いところ

1. 複数のQueryCleintインスタンスを作成していないか

基本的にQueryClientのインスタンスはアプリケーションライフサイクルにおいて、一つだけ作成すべき。
誤って複数のQueryCleintインスタンスを作成していないか確認しよう。

NG例 ❌
/* eslint "@tanstack/query/stable-query-client": "error" */

function App() {
  const queryClient = new QueryClient()
  return (
    <QueryClientProvider client={queryClient}>
      <Home />
    </QueryClientProvider>
  )
}
OK例1 ⭕️
function App() {
  const [queryClient] = useState(() => new QueryClient())
  return (
    <QueryClientProvider client={queryClient}>
      <Home />
    </QueryClientProvider>
  )
}
OK例2 ⭕️
const queryClient = new QueryClient()
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Home />
    </QueryClientProvider>
  )
}
OK例3 ⭕️
async function App() {
  const queryClient = new QueryClient()
  await queryClient.prefetchQuery(options)
}

2. enabledオプションがfalseになっているクエリに対しては、invalidateQueriesrefetchQueriesは使えない

それはそうという感じだが、一応確認しておこう。

NG例 ❌
function Todos() {
  const { data, isFetching } = useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
    // enabled=falseのクエリは、invalidateQueries()やrefetchQueries()の影響を受けない
    enabled: false,
  })

  return (...)
}

3. QueryClientインスタンスへのアクセスはuseQueryClientを使う

QueryClientProviderを利用している場合は、useQueryClientフックを利用してQueryClientインスタンスにアクセスしよう。

NG例 ❌
const createTodoMutation = useMutation(postTodo, {
  onSuccess: async () => {
    const queryClient = new QueryClient();
    await queryClient.invalidateQueries("todos");
  },
});
OK例 ⭕️
import { useQueryClient } from '@tanstack/react-query'

const queryClient = useQueryClient()

const createTodoMutation = useMutation(postTodo, {
  onSuccess: async () => {
    await queryClient.invalidateQueries("todos");
  },
});

4. queryKeyが誤っている

invalidateQueriesrefetchQueriesに渡しているqueryKeyが誤っていないか確認しよう。

5. invalidateQueriesrefetchQueriesが実行される前に画面遷移したり、コンポーネントをアンマウントしてしまっている

NG例 ❌
import { useQueryClient } from '@tanstack/react-query'

const queryClient = useQueryClient()

const createTodoMutation = useMutation(postTodo, {
  onSuccess: async () => {
    // ここで画面遷移してしまうと、後続の処理が実行されない
    // コンポーネントのアンマウントも同様(ダイアログの開閉など要注意)
    router.push("/todos")
    await queryClient.invalidateQueries("todos");
  },
});

6. invalidateQueriesしようとしているクエリがinactiveである

invalidateQueriesは、デフォルトだとactiveなクエリのみをinvalidateするため、
クエリがinactiveな状態である場合(画面遷移した時やコンポーネントがアンマウントされた場合など)は、対象に含まれない。
inactiveなものも対象に含める場合は、refetchTypeオプションを利用する必要がある。

0
1
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?