Kento
Tanstack QueryのqueryKeysとは?キャッシュ管理と更新後の再取得を理解する
2026年10月25日
見出しはありません
要約を生成中...
個人開発でTanstack Queryを使っているのですが、まだTanstackQueryについて理解が曖昧なので、メモ用として残しています。
ユーザープロフィールの編集画面でユーザーの各SNSのURLを設定し、ユーザープロフィール画面で追加したSNSのアイコンが表示されるような機能を実装していました。 しかし、SNSを設定して更新してもSNSアイコンが表示されず、再度リロードしたらアイコンが表示されるバグが起きたのです。


そもそも、QueryKeysとは何なのか? サーバーから取得した(APIレスポンス)をキャッシュし、識別するための一意のキーのこと。 TanstackQueryではデータ取得の場合、最上位レベルで単一の文字列を配列に書く必要があります。 また、QueryKeysはTanStack Query内部でキャッシュするための名前なので、レスポンスに合わせた名前でなくても動作には支障ないっぽいです。(確認済み)
以下の例はシンプルな書き方ですが、様々な形式にも対応も可能です!
詳しくは公式を参照!!
/*
queryKey: 取得データを識別・キャッシュするため
queryFn: データを取得する関数
*/
export const useGetFetcher = <TResponse>(queryKey: QueryKey, path: string) => {
return useQuery<TResponse>({
queryKey,
queryFn: () => getFetcher<TResponse>(path),
});
};
const { data: userProfile, error } = useGetFetcher<UserProfileResponse>(
["user"],
`/public/profile`,
);
前提QueryKeysを理解せずに、データ取得時のQueryKeysの名前とキャッシュを更新する時のQueryKeysの名前が不一致のことが原因でした。
データの作成・更新・削除では、useMutationを呼び出して活用します。
データ取得時のQueryKeysの名前は、userで、handleSave関数内にある、queryClient.invalidateQueriesのQueryKeysでは、profileとなっているのがわかると思います。
ちなみに、invalidateQueriesは、取得したデータを自動でキャッシュして、最新情報を再取得する時に使います!
import { useMutation } from '@tanstack/react-query';
// PUTメソッドを、Tanstack Queryから実行
export const usePut = <TRequest, TResponse>(path: string) => {
return useMutation<TResponse, Error, TRequest>({
mutationFn: (data) => putFetcher<TRequest, TResponse>(path, data),
});
};
const { mutate: upDateProfile, isPending: isUpdating } = usePut<
Profile,
UpdateUserProfile
>(`/admin/profile`);
const handleSave = (profileValue: Profile) => {
upDateProfile(profileValue, {
onSuccess: (response) => {
toast.success(response.message);
dispatch("close");
setMode("View");
queryClient.invalidateQueries({ queryKey: ["profile"] });
},
onError: () => {
toast.error("プロフィールの更新に失敗しました。");
},
});
};
これがなぜ同じ名前のQueryKeysじゃないといけないのか。 以下例です。
人間の目から見ると、同じユーザープロフィールの情報なのかなと見えますが、 TanstackQueryでは別の住所の情報として捉えます。
取得したuserのデータをキャッシュしています。
一方、profileで指定されているため、userのデータのキャッシュが無効化されず、古い情報のまま表示されたということになります。
なので、取得したデータのQueryKeysと更新するQueryKeysは同じ名前にする必要があるってことです。
// 取得したQueryKeys
["user"]
// 更新するQueryKeys
["profile"]
queryCache = {
'["user"]': プロフィール取得時,
'["profile"]': 別のキャッシュの領域,
};
ミスをきっかけに、QueryKeysのことについて調べるいい機会となりました〜
要約
コメント
まだコメントはありません。