由于 ReactJS 重新渲染,事件发射器内存泄漏
Event Emitter memory leak because of ReactJS Rerendering
祝您今天过得愉快✌感谢您的提前帮助。
我正在使用 ElectronJS 和 React 构建一个网络浏览器。我正在使用 ipcMain 和 ipcRenderer 在后端和前端之间发送事件,它们只是 EventEmitter class.
的子级
我正在处理的问题是 EventEmitter 泄漏。我的 React 前端发送一个事件,后端 returns 数据。 React 然后将此数据分配给它的状态,这会导致重新渲染,然后创建另一个事件侦听器。这会创建一堆事件侦听器,然后出现内存泄漏错误。
这是我的 React 组件的示例
export const CoreLayout = props => {
const [tablist, setTablist] = useState([]);
window.ipcRenderer.on('receive-tabs', (_, data) => {
setTablist(data);
});
console.log('rerender2')
return (
<div className="flex flex-col w-full min-h-screen bg-night-600">
<Header tablist={tablist} isMaximized={props.isMaximized} />
</div>
)
}
要在 render
中实现副作用,您应该始终考虑 useEffect
。在您的情况下,当组件结束其生命周期(已卸载)时,您通常需要删除事件侦听器。
见https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup for instructions how to set up a side effect with an automatic clean-up. To avoid re-running this on each render, you'll want an empty dependency array, as described here in the big, yellow Note section: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.
useEffect(()=>{
const listener= (_, data) => {
setTablist(data);
};
window.ipcRenderer.on('receive-tabs', listener);
return ()=>{
window.ipcRenderer.removeListener('receive-tabs', listener);
}
});
祝您今天过得愉快✌感谢您的提前帮助。
我正在使用 ElectronJS 和 React 构建一个网络浏览器。我正在使用 ipcMain 和 ipcRenderer 在后端和前端之间发送事件,它们只是 EventEmitter class.
的子级我正在处理的问题是 EventEmitter 泄漏。我的 React 前端发送一个事件,后端 returns 数据。 React 然后将此数据分配给它的状态,这会导致重新渲染,然后创建另一个事件侦听器。这会创建一堆事件侦听器,然后出现内存泄漏错误。
这是我的 React 组件的示例
export const CoreLayout = props => {
const [tablist, setTablist] = useState([]);
window.ipcRenderer.on('receive-tabs', (_, data) => {
setTablist(data);
});
console.log('rerender2')
return (
<div className="flex flex-col w-full min-h-screen bg-night-600">
<Header tablist={tablist} isMaximized={props.isMaximized} />
</div>
)
}
要在 render
中实现副作用,您应该始终考虑 useEffect
。在您的情况下,当组件结束其生命周期(已卸载)时,您通常需要删除事件侦听器。
见https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup for instructions how to set up a side effect with an automatic clean-up. To avoid re-running this on each render, you'll want an empty dependency array, as described here in the big, yellow Note section: https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run.
useEffect(()=>{
const listener= (_, data) => {
setTablist(data);
};
window.ipcRenderer.on('receive-tabs', listener);
return ()=>{
window.ipcRenderer.removeListener('receive-tabs', listener);
}
});