2016-11-24 117 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