最简单的解决方案是使用局部变量来跟踪组件是否已安装。这是基于类的方法的常见模式。这是一个使用钩子实现它的示例:
function Example() { const [text, setText] = React.useState('waiting...'); React.useEffect(() => { let isCancelled = false; simulateSlowNetworkRequest().then(() => { if (!isCancelled) {setText('done!'); } }); return () => { isCancelled = true; }; }, []); return <h2>{text}</h2>;}
这里是一个替代与useRef(见下文)。请注意,依赖项列表无法解决。第一次渲染后,ref的值将保持为true。在这种情况下,第一种解决方案更合适。
function Example() { const isCancelled = React.useRef(false); const [text, setText] = React.useState('waiting...'); React.useEffect(() => { fetch(); return () => { isCancelled.current = true; }; }, []); function fetch() { simulateSlowNetworkRequest().then(() => { if (!isCancelled.current) {setText('done!'); } }); } return <h2>{text}</h2>;}
您可以在本文中找到有关此模式的更多信息。这是GitHub上React项目中的一个问题,展示了此解决方案。
解决方法我收到此错误:
无法在已卸载的组件上执行React状态更新。这是空操作,但它表明应用程序中发生内存泄漏。要修复,请取消使用useEffect清理功能中的所有订阅和异步任务。
当开始获取数据并卸载组件时,但是函数试图更新已卸载组件的状态。
解决此问题的最佳方法是什么?
CodePen示例。
default function Test() { const [notSeenAmount,setNotSeenAmount] = useState(false) useEffect(() => {let timer = setInterval(updateNotSeenAmount,2000)return () => clearInterval(timer) },[]) async function updateNotSeenAmount() {let data // here i fetch datasetNotSeenAmount(data) // here is problem. If component was unmounted,i get error. } async function anotherFunction() { updateNotSeenAmount() //it can trigger update too } return <button onClick={updateNotSeenAmount}>Push me</button> //update can be triggered manually}