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

React-Query useMutation onError中console.log(email)输出空值问题

React-Query useMutation onError打印email为空的问题解决

问题原因

  1. 执行顺序偏差:请求失败后,React-Query会优先触发onError回调,之后才会更新isError状态并触发对应的useEffect。所以onError执行时,setEmail("hi isError")还未执行,email仍是初始空字符串。
  2. 闭包陷阱:即使setEmail提前执行,onError回调是组件初次渲染时创建的,它捕获的是当时的email值(空字符串);状态更新后组件重新渲染,但旧的onError函数不会更新,依然拿不到新状态。

解决方案

方案一:直接在onError中处理状态与打印

不需要依赖isError的useEffect,直接在onError里完成状态设置和打印,彻底避免执行顺序问题:

export const googleLogin = (data: any) => {
  return axios.post("/login/google", data).then(({ data }) => data as any);
};

const [email, setEmail] = useState<string>("");
const { mutate, isLoading, isError } = useMutation(googleLogin, {
  onError(error: AxiosError) {
    const newEmail = "hi isError";
    setEmail(newEmail);
    console.log(newEmail); // 直接使用要设置的变量,无需依赖state
  },
});

function handleSocialLogin(event: React.MouseEvent<HTMLElement> & any) {
  mutate({
    clientIp: "hi",
  });
}

return <button onClick={handleSocialLogin}>button</button>;

方案二:用useRef跟踪最新状态

如果必须保留useEffect的逻辑,可通过useRef存储最新的email值,避开闭包陷阱:

export const googleLogin = (data: any) => {
  return axios.post("/login/google", data).then(({ data }) => data as any);
};

const [email, setEmail] = useState<string>("");
const emailRef = useRef<string>("");

// 同步state到ref,确保ref始终持有最新值
useEffect(() => {
  emailRef.current = email;
}, [email]);

const { mutate, isLoading, isError } = useMutation(googleLogin, {
  onError(error: AxiosError) {
    // 延迟执行,确保isError的useEffect已完成状态更新
    setTimeout(() => {
      console.log(emailRef.current);
    }, 0);
  },
});

useEffect(() => {
  if (isError) {
    setEmail("hi isError");
  }
}, [isError]);

function handleSocialLogin(event: React.MouseEvent<HTMLElement> & any) {
  mutate({
    clientIp: "hi",
  });
}

return <button onClick={handleSocialLogin}>button</button>;

方案三:在isError的useEffect中完成打印

如果逻辑必须通过监听isError来设置状态,那么打印操作应该放在同一个useEffect里,确保状态更新后立即执行:

export const googleLogin = (data: any) => {
  return axios.post("/login/google", data).then(({ data }) => data as any);
};

const [email, setEmail] = useState<string>("");
const { mutate, isLoading, isError } = useMutation(googleLogin);

useEffect(() => {
  if (isError) {
    const newEmail = "hi isError";
    setEmail(newEmail);
    console.log(newEmail); // 直接使用变量,或在下一次渲染时打印email
  }
}, [isError]);

function handleSocialLogin(event: React.MouseEvent<HTMLElement> & any) {
  mutate({
    clientIp: "hi",
  });
}

return <button onClick={handleSocialLogin}>button</button>;

内容的提问来源于stack exchange,提问作者김민수

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:40:16