2016-11-24 98 views
1

我目前正面临React问题。我需要知道何时从DOM中删除组件。ReactJs如何知道何时从DOM中删除组件

我在组件生命周期中发现的所有componentWillUnmount都是在组件从DOM中删除之前调用的。

有什么办法可以用React来实现这个吗? 在普通的JavaScript?

感谢。

[编辑]

@jpdelatorre “普通的JavaScript” ===不使用库;-)

我的使用情况是一个反应构件内使用的jsPlumb。

基本上jsPlumb是一个在位置计算中绘制DOM中的svg的库。

在我的主要组件中有一个项目列表。 每个项目是一个组件。 在每个渲染项目上,我使用JsPlumb在其上绘制。

但是...当我删除列表中的项目时,这些项目正在改变DOM中的位置,所以我需要让jsPlumb根据新的位置重新绘制事物。所以这就是为什么我需要知道组件何时完全从DOM中删除。

+0

你可以扩大你的问题一点点......也许提供你的用例为什么你想这样做。 “纯JavaScript”是什么意思?不使用库?不使用ES6功能? – jpdelatorre

+0

@jpdelatorre看到我的[编辑]了解更多信息 – pitrackster

回答

0

好的,谢谢大家!我发现一个解决方案,符合我的需求,并(恕我直言)干净...

在我的父组件处理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 
    } 

} 
1

componentWillUnmount是正确的生命周期方法。正如你所说,它是在组件被移除之前触发的。如果您有需要等待的时间,直到它被移除后,可以使用setTimeout以及较短的超时值来安排当前任务完成后的回调。

+0

感谢您的回答。设置超时是我目前正在做的事情......我正在寻找一种“更清洁”的解决方案,但谢谢! – pitrackster

+0

@pitrackster:据我所知,没有一个。 React源中唯一的地方是我可以找到对'componentWillUnmount'的调用,然后实际上卸载它,没有干预的回报,并且没有进一步调用组件。 –

1

componentWillUnmount是可以挂钩的生命周期方法。

但是,如果您想知道component1中有关卸载component2的信息,那么您需要在其生命周期方法中触发component2中的操作,该操作应在component1中订阅,并在component1侦听器中执行一些操作。

+0

是的,这就是我现在如何处理它,有一个超时...我从大家看到答案,没有其他解决方案... – pitrackster

+0

为什么超时?您可以通过订阅由另一个组件触发的事件来达到目的。 –

+0

componentWillUnmount不会告诉我什么时候组件真的从DOM中删除,但说“嗨,我会被删除......不久或稍后”...这就是为什么我需要使用超时...因为我需要在组件消失后做些事情! – pitrackster

1

正如其他已经提到你需要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

+0

感谢您的详细解答。不幸的是,它不能解决我的问题。如果我想等待从DOM中删除'红色按钮',我需要用一个任意时间的超时...这是不可靠的IMO ......但似乎没有其他方式... – pitrackster

+0

@pitrackster你能解释一下吗?你什么时候需要一个活动?当按钮被删除时,之前或之后? – wolendranh

+0

@pitracksterI更新了答案。 – wolendranh

相关问题