ReactJs如何知道何时从DOM中删除组件
我目前正面临React问题。我需要知道何时从DOM中删除组件。ReactJs如何知道何时从DOM中删除组件
我在组件生命周期中发现的所有componentWillUnmount都是在组件从DOM中删除之前调用的。
有什么办法可以用React来实现这个吗? 在普通的JavaScript?
感谢。
[编辑]
@jpdelatorre “普通的JavaScript” ===不使用库;-)
我的使用情况是一个反应构件内使用的jsPlumb。
基本上jsPlumb是一个在位置计算中绘制DOM中的svg的库。
在我的主要组件中有一个项目列表。 每个项目是一个组件。 在每个渲染项目上,我使用JsPlumb在其上绘制。
但是...当我删除列表中的项目时,这些项目正在改变DOM中的位置,所以我需要让jsPlumb根据新的位置重新绘制事物。所以这就是为什么我需要知道组件何时完全从DOM中删除。
好的,谢谢大家!我发现一个解决方案,符合我的需求,并(恕我直言)干净...
在我的父组件处理componentDidUpdate生命周期事件,在那里我可以知道(与prevProps和道具)如果所做的更改需要火我的动作...
class MyComponent extends Component {
// this one is called each time any props is changed
componentDidUpdate(prevProps, prevState) {
// if condition is matched then do something
}
}
componentWillUnmount
是正确的生命周期方法。正如你所说,它是在组件被移除之前触发的。如果您有需要等待的时间,直到它被移除后,可以使用setTimeout
以及较短的超时值来安排当前任务完成后的回调。
感谢您的回答。设置超时是我目前正在做的事情......我正在寻找一种“更清洁”的解决方案,但谢谢! – pitrackster
@pitrackster:据我所知,没有一个。 React源中唯一的地方是我可以找到对'componentWillUnmount'的调用,然后实际上卸载它,没有干预的回报,并且没有进一步调用组件。 –
componentWillUnmount是可以挂钩的生命周期方法。
但是,如果您想知道component1中有关卸载component2的信息,那么您需要在其生命周期方法中触发component2中的操作,该操作应在component1中订阅,并在component1侦听器中执行一些操作。
是的,这就是我现在如何处理它,有一个超时...我从大家看到答案,没有其他解决方案... – pitrackster
为什么超时?您可以通过订阅由另一个组件触发的事件来达到目的。 –
componentWillUnmount不会告诉我什么时候组件真的从DOM中删除,但说“嗨,我会被删除......不久或稍后”...这就是为什么我需要使用超时...因为我需要在组件消失后做些事情! – pitrackster
正如其他已经提到你需要componentWillUnmount
。 这里是反应的简单的例子(我加了有一些评论让正在发生的事情之一):
var Button = React.createClass({
componentWillUnmount: function(){
// console will show this message when compoent is being Unmounted("removed")
console.log('Button removed');
},
render() {
return <h1 ref='button_node'>
<ReactBootstrap.Button bsStyle="success">Red</ReactBootstrap.Button>
</h1>;
}
});
var RemoveButton = React.createClass({
getInitialState: function() {
// this state keep tracks if Button removed or not
//(you can use it for some redrawing or anything else in your code)
return {buttonMounted: true}
},
mountRedButton: function(){
ReactDOM.render(<Button/>, document.getElementById('button'));
this.setState({buttonMounted: true});
},
unmountRedButton: function(){
ReactDOM.unmountComponentAtNode(document.getElementById('button'));
this.setState({buttonMounted: false});
},
render() {
return <h1>
//based on condition if Button compoennt removed or not we show/hide different buttons
{ this.state.buttonMounted ? <ReactBootstrap.Button onClick={this.unmountRedButton } bsStyle="danger">Remove Red Button!</ReactBootstrap.Button> : null}
{ this.state.buttonMounted ? null :<ReactBootstrap.Button onClick={this.mountRedButton } bsStyle="success">Add Red Button!</ReactBootstrap.Button> }
</h1>;
}
});
// mount components
ReactDOM.render(<Button/>, document.getElementById('button'));
ReactDOM.render(<RemoveButton/>, document.getElementById('remove'));
这里是JSFiddle
随着对“普通的JavaScript”一个完整的工作的例子 - 你是已经使用阵营JS,我的例子是基于反应,ReactDom,仅此而已(其实有也反应过来的自举,我说只为漂亮的按钮,它根本不需要)
更新: 什么关于使用MutationObserver ?如果你需要一段时间去除DOM中的节点,但在删除节点之前触发componentWillUnmount
(这对你来说似乎是不可改变的),你可以使用它。按照我的按钮示例:
var removalWatcher = new MutationObserver(function (e) {
var removalTimeStamp = '[' + Date.now() + '] ';
if (e[0].removedNodes.length) {
console.log('Node was removed', e[0].removedNodes, 'timestamp:', removalTimeStamp)
};
});
这里是一个带有更新示例的JsFiddle。您可以比较打印到控制台中的时间戳MutationObserver
和React ComponentWillUnmount
。
感谢您的详细解答。不幸的是,它不能解决我的问题。如果我想等待从DOM中删除'红色按钮',我需要用一个任意时间的超时...这是不可靠的IMO ......但似乎没有其他方式... – pitrackster
@pitrackster你能解释一下吗?你什么时候需要一个活动?当按钮被删除时,之前或之后? – wolendranh
@pitracksterI更新了答案。 – wolendranh
你可以扩大你的问题一点点......也许提供你的用例为什么你想这样做。 “纯JavaScript”是什么意思?不使用库?不使用ES6功能? – jpdelatorre
@jpdelatorre看到我的[编辑]了解更多信息 – pitrackster