如何解决React应用中「无法对已卸载组件更新状态」的报错
报错原因
这个警告是因为你的CsvFileReader组件内设置了1秒延迟的setTimeout回调,触发回调时用来更新的info所属的CsvFile组件已经被卸载了,异步回调还尝试更新已卸载组件的状态就会触发这个警告,确实存在内存泄漏的风险。
解决方法
方案1:清理异步定时器(最优)
在CsvFileReader组件内新增定时器引用,组件卸载时直接清除未执行的定时器,从根源避免更新已卸载组件的状态,修改后的代码如下:
import { useRef, useEffect } from 'react'; const CsvFileReader = ({ setInfo }) => { // 存储定时器id const timerRef = useRef(null); const handleOnDrop = data => { const infos = data.map(item => item.data); // 保存当前定时器id timerRef.current = setTimeout(() => setInfo([...infos]), 1000); }; const handleOnError = (err, file, inputElem, reason) => { console.log(err); }; const handleOnRemoveFile = data => { console.log(data); }; // 组件卸载时清除定时器 useEffect(() => { return () => { if (timerRef.current) { clearTimeout(timerRef.current); } }; }, []); return ( <> <MainReader> <CSVReader onDrop={handleOnDrop} onError={handleOnError} config={ (({ fastMode: true }, { chunk: "LocalChunkSize" }), { header: false }) } addRemoveButton onRemoveFile={handleOnRemoveFile} > {/* 剩余原有代码保持不变即可 */}
方案2:优化父组件key设置
你当前父组件渲染DataSide时用了index作为key,如果你有动态调整组件顺序、切换组件类型的操作,用index作为key会导致组件不必要的卸载重渲染,把key替换为唯一的id即可,修改父组件代码:
const eachComponent = (index, id) => ( // 把key从index换成唯一的id参数 <DataSide id={id} key={id} onClick={chartItself}> {/* 剩余原有代码保持不变即可 */}
两个方案搭配使用即可彻底消除该警告。
内容的提问来源于stack exchange,提问作者KYUN
相关产品推荐
相关产品推荐

