2017-04-12 41 views
1

該問題在代碼片段中的評論中大致概括。當我在constructor中綁定this._setSize時,它從不知道this.container - 即使在componentDidMount中調用。我究竟做錯了什麼?謝謝!在React ComponentDidMount中獲取引用和附加事件偵聽器的正確方法?

export default class MyComponent extends React.Component { 
 
    constructor() { 
 
    super() 
 
    this._setSize = this._setSize.bind(this) 
 
    } 
 

 
    componentDidMount() { 
 
    const container = this.container // <div></div> :) 
 
    this._setSize() 
 
    window.addEventListener('resize', this._setSize) 
 
    } 
 

 
    componentWillUnmount() { 
 
    window.addEventListener('resize', this._setSize) 
 
    } 
 

 
    _setSize() { 
 
    const container = this.container // undefined :(
 
    const containerSize = { 
 
     x: container.offsetWidth, 
 
     y: container.offsetHeight 
 
    } 
 
    this.setState({ containerSize }) 
 
    } 
 

 
    render() { 
 
    return (
 
     <div ref={node => this.container = node}> 
 
     </div> 
 
    ) 
 
    } 
 
}

回答

4

在每個重新渲染要創建和傳遞功能的新實例設置容器REF。然後用null調用前一個函數。因此,它可能發生,你不小心設置this.containernull:當你路過這裏的組件實例方法,而不是內聯函數

<div ref={node => this.container = node}> 

,它與組件卸載過程中參考和第二次與null調用一次。例如:

// dont forget to bind it in constructor 
onContainerRef (node) { 
    // furthermore you can even check if node is not null 
    // if (node) { ... 
    this.container = node 
} 

// ... in render 
<div ref={this.onContainerRef}> 

你可以在docs瞭解更多。

1

我定你的代碼,它的工作現在:see working DEMO

什麼問題?

componentWillUnmount() { 
    window.addEventListener('resize', this._setSize) 
} 

你沒有因爲componentWillUnmount你有addEventListener,而不是從removeEventListener刪除window事件偵聽器。如果您有任何組件的有條件渲染,則在resize事件_setSize也將被調用。

爲了說明這個問題,用破碎的演示播放和點擊Toggle按鈕,並期待在輸出:see broken DEMO

相關問題