You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TanStack Query中getQueryData读取缓存始终返回undefined问题求助

TanStack Query useMutation 缓存读取问题解决

问题场景

调用useMutation完成登录请求并拿到预期数据后,使用getQueryData(['authData'])读取对应key的缓存始终返回undefined。

相关代码

用于创建Mutation的代码:

const axiosInstance = axios.create(habiticaAPIconf);

function parseResponse(response:LoginDataContract):AuthData{
  return {
    id: response.data.id,
    apiToken: response.data.apiToken,
    username: response.data.username
  }
}

const getAuthenticationData = async (userCredentials:UserCredentials):Promise<AuthData> => {
  const response = await axiosInstance.post<LoginDataContract>("/user/auth/local/login", {...userCredentials});
  return parseResponse(response.data);
}

export function useCredentialData() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
    mutationKey: ['authData']
  });
};

触发Mutation的组件:

export function LoginForm() {
  const { mutate, isSuccess, data } = useCredentialData();

  function handleLogin(e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) {
    e.preventDefault();
    mutate({
      username: (document.getElementById("email") as HTMLInputElement).value,
      password: (document.getElementById("password") as HTMLInputElement).value
    });
    console.log(data); // 同步调用无法拿到异步mutation的结果
  }

  return (
    <form>
      <label htmlFor="email">
        <input type="email" name="email" id="email"></input>
      </label>
      <label htmlFor="password">
        <input type="password" name="password" id="password"></input>
      </label>
      <button type="submit" onClick={ (e)=> {handleLogin(e)}}>Login</button>
      <span>{isSuccess ? `${data.username}` : ""}</span>
    </form>
  )
}

读取缓存的组件:

import { useQueryClient } from "@tanstack/react-query";

export function SidebarTasksList() {
  const queryClient = useQueryClient();

  return (
    <section>
      <button onClick={
        ()=>console.log(queryClient.getQueryData(['authData']))
      }>CLICK</button>
    </section>
  );
}

原因分析

useMutation的mutationKey仅用于标识mutation实例(比如跟踪状态、取消请求等),不会自动将mutation结果存入Query缓存。Query缓存的读写依赖独立的queryKey,和mutationKey是完全分离的概念,因此直接用getQueryData读取['authData']会返回undefined。

解决方案

在useMutation的onSuccess回调中,手动调用queryClient.setQueryData将mutation结果写入指定queryKey对应的缓存:

修改useCredentialData函数,新增onSuccess配置:

export function useCredentialData() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
    mutationKey: ['authData'],
    // 登录成功后将数据写入Query缓存
    onSuccess: (authData) => {
      queryClient.setQueryData(['authData'], authData);
    }
  });
};

修改完成后,mutation执行成功时,结果会被写入['authData']对应的缓存,此时SidebarTasksList组件中调用queryClient.getQueryData(['authData'])即可正确读取登录数据。

额外说明:LoginForm中的console.log(data)是同步执行的,无法拿到异步mutation的实时结果;若需要在mutation完成后处理数据,可使用mutate的回调函数或监听isSuccess状态变化。

内容的提问来源于stack exchange,提问作者jazzgot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:54:55