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

Formik提交时React状态更新警告:已卸载组件无法更新状态

Fixing "Can't perform a React state update on an unmounted component" Warning in Formik Submit

这个警告的核心问题在于:当你的异步请求(也就是recoveryPassword的dispatch操作)还在处理时,组件可能已经被卸载了(比如用户中途跳转到了其他页面),但请求完成后你依然尝试更新recovered状态,这就触发了React的内存泄漏警告。

解决方案:跟踪组件挂载状态

我们可以通过useRef来保存组件的挂载状态,在异步操作完成后先检查这个状态,再执行状态更新,避免对已卸载组件的无效操作:

  1. 首先在组件中添加挂载状态的ref:
const isMounted = React.useRef(true);
  1. 用useEffect设置组件卸载时的清理逻辑:
React.useEffect(() => {
  return () => {
    isMounted.current = false;
  };
}, []);
  1. 修改你的handleSubmit函数,在更新状态前先校验组件是否仍挂载:
const handleSubmit = async (values) => {
  setLoading(true);
  try {
    const response = await dispatch(recoveryPassword(values.email));
    // 仅当组件处于挂载状态时,才更新recovered
    if (isMounted.current && response.status === 200) {
      setRecovered(true);
    }
  } finally {
    // 同样校验挂载状态后再更新loading
    if (isMounted.current) {
      setLoading(false);
    }
  }
};

为什么setLoading没触发警告?

其实不是setLoading绝对不会触发,只是大概率在setLoading(false)执行时,组件还没完成卸载;而setRecovered(true)执行时,组件已经被卸载了。通过统一添加挂载状态检查,可以彻底避免所有异步操作后的无效状态更新警告。

另外,如果你使用Redux Toolkit的话,也可以用createAsyncThunk来处理异步action,它内置了请求取消逻辑,能更优雅地解决这类问题,但上面的方案已经可以直接解决你当前的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:06:05