Formik提交时React状态更新警告:已卸载组件无法更新状态
Fixing "Can't perform a React state update on an unmounted component" Warning in Formik Submit
这个警告的核心问题在于:当你的异步请求(也就是recoveryPassword的dispatch操作)还在处理时,组件可能已经被卸载了(比如用户中途跳转到了其他页面),但请求完成后你依然尝试更新recovered状态,这就触发了React的内存泄漏警告。
解决方案:跟踪组件挂载状态
我们可以通过useRef来保存组件的挂载状态,在异步操作完成后先检查这个状态,再执行状态更新,避免对已卸载组件的无效操作:
- 首先在组件中添加挂载状态的ref:
const isMounted = React.useRef(true);
- 用
useEffect设置组件卸载时的清理逻辑:
React.useEffect(() => { return () => { isMounted.current = false; }; }, []);
- 修改你的
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
相关产品推荐
相关产品推荐

