[英]Is there any way to perform a cleanup function before the new render on a functional component
I have SomeComponent which uses a some library (we'll call domLib ) that mutates the DOM directly (eg modifies and adds several elements & listeners).我有SomeComponent它使用一个库(我们将调用domLib )直接改变 DOM(例如修改和添加几个元素和侦听器)。 SomeComponent also accepts props data which domlib uses
SomeComponent还接受domlib使用的道具数据
const SomeComponent = ({ data }) => {
useEffect(() => {
domLib.init(data, 'example-container');
return () => { //cleanup function
domLib.destroy('example-container'); //removes everything from example-container, listeners etc from example-container
}
},[data])
return (<div id='example-container'>
<HelpComponent data={data}/>
</div>)
}
domLib must also be able to see/modify HelpComponent or the children of ' example-container ' domLib还必须能够查看/修改HelpComponent或“ example-container ”的子项
When receiving new props/updating, since the cleanup function runs AFTER render, the domLib.destroy('example-container');
当接收新的道具/更新时,由于清理 function在渲染后运行,
domLib.destroy('example-container');
removes the children of example-container which means <HelpComponent data={data}/>
will also be removed移除example-container的孩子,这意味着
<HelpComponent data={data}/>
也将被移除
useEffect(() => {
domLib.destroy('example-container');
ReactDom.unmountComponentAtNode(document.getElementById('example-container'))
ReactDom.render(<HelpComponent data={data}/>, document.getElementById('example-container'))
domLib.init(data, 'example-container');
})
return (<div id='example-container'>
{/* removed */}
</div>)
Attempt , Create everything inside the useEffect hook using ReactDom and remove everything I need to right before it.尝试,使用ReactDom在useEffect钩子中创建所有内容,并在它之前删除我需要的所有内容。
Issue , the render method in ReactDom.render(<HelpComponent data={data}/>, document.getElementById('example-container'))
does not immediately apply changes to the DOM therefore when domLib cannot see HelpComponent问题,
ReactDom.render(<HelpComponent data={data}/>, document.getElementById('example-container'))
中的渲染方法不会立即将更改应用到 DOM,因此当domLib看不到HelpComponent
Edit for extra clarity编辑以获得额外的清晰度
The library domLib is jsPlumb which I am using to create links between elements. domLib 库是jsPlumb ,我用它来创建元素之间的链接。 The elements are created based on the data prop, and the lib jsPlumb creates links between those elements.
元素是基于 data 属性创建的,lib jsPlumb 在这些元素之间创建链接。
The issue is the elements created from jsPlumb are outside of the react ecosystem, so it remains between updates, therefore I need to remove them between updates问题是从 jsPlumb 创建的元素在反应生态系统之外,所以它仍然在更新之间,因此我需要在更新之间删除它们
Add []
as a second argument for useEffect
so it would run once.添加
[]
作为useEffect
的第二个参数,以便它运行一次。 If you need any props for your lib, add them to watch after changes.如果您的库需要任何道具,请将它们添加到更改后观看。 Your hook would run only then.
你的钩子只会在那时运行。 For more great information, written by Dan: https://overreacted.io/a-complete-guide-to-useeffect/ or docs: https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect
有关更多重要信息,由 Dan 编写: https://overreacted.io/a-complete-guide-to-useeffect/或文档: https://reactjs.org/docs/hooks-reference.html#conditionally-firing-效果
EDIT: to watch certain props changes, add them to the square brackets in useEffect
.编辑:要观看某些道具更改,请将它们添加到
useEffect
中的方括号中。 An example from the docs:文档中的一个示例:
useEffect(
() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
},
[props.source],
);
If you want to call destroy method just once, not depending on data changes, do this:如果您只想调用一次 destroy 方法,而不依赖于数据更改,请执行以下操作:
useEffect(
() => {
return () => {
subscription.unsubscribe();
};
},
[],
);
Empty function body would do nothing on the first run, but the returned function would run on destroy.空的 function 主体在第一次运行时不会执行任何操作,但返回的 function 将在销毁时运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.