[英]Can't perform a React state update on an unmounted component with EventListener
I have the following piece of code on which I am getting warning two warnings:我有以下代码,我收到了两个警告:
Warning: Can't perform a React state update on an unmounted component.
警告:无法对未安装的组件执行 React state 更新。 This is a no-op, but it indicates a memory leak in your application.
这是一个空操作,但它表明您的应用程序中存在 memory 泄漏。 To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
要修复,请取消 useEffect 清理中的所有订阅和异步任务 function。
unmountComponentAtNode(): The node you're attempting to unmount was rendered by another copy of React.
unmountComponentAtNode():你试图卸载的节点是由 React 的另一个副本渲染的。
import React, { useState, useEffect } from "react";
import GravatarList from "./GravatarList";
import Header from "./Header";
import { calculateNumberOfImages } from "./utils";
const App = () => {
const handle = () => {
setState({ images: calculateNumberOfImages() });
}
useEffect(() => {
return () => {
window.removeEventListener('resize', () => handle())
window.removeEventListener('scroll', () => handle())
}
}, [])
const [state, setState] = useState(() => {
window.addEventListener("scroll", () => handle());
window.addEventListener("resize", () => handle());
return { images: calculateNumberOfImages() };
});
return (
<div>
<Header />
<GravatarList state={state} />
</div>
);
};
export default App;
I can't seem to figure out what I am doing wrong as I have already cleared the listeners in useEffect
.我似乎无法弄清楚我做错了什么,因为我已经清除了
useEffect
中的侦听器。
The issue here is that the event callbacks you are trying to remove aren't the same callbacks you added to begin with.这里的问题是您尝试删除的事件回调与您一开始添加的回调不同。 The issue is because you are using anonymous functions to call the function updating state.
问题是因为您正在使用匿名函数调用 function 更新 state。
You should also not use the state initializer function to do side effects like adding event listeners.您也不应该使用 state 初始值设定项 function 来执行添加事件侦听器等副作用。
Move the handle
callback and adding of event listeners into the mounting useEffect
hook.将
handle
回调和事件侦听器添加到安装的useEffect
挂钩中。 Pass the handle
callback reference to the add/remove functions,将
handle
回调引用传递给添加/删除函数,
const App = () => {
const [state, setState] = useState(() => ({
images: calculateNumberOfImages()
}));
useEffect(() => {
const handle = () => {
setState({ images: calculateNumberOfImages() });
};
window.addEventListener("scroll", handle);
window.addEventListener("resize", handle);
return () => {
window.removeEventListener('resize', handle);
window.removeEventListener('scroll', handle);
}
}, []);
return (
<div>
<Header />
<GravatarList state={state} />
</div>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.