2016-11-30 23 views
0

我有這個strage情況下,也許我失蹤如何反應componentDidMount的作品,也許這是一個奇怪的行爲(右知道我不能提供一個真正的小提琴與jQuery插件的東西,但我敢肯定的問題比插頭本身更寬)。爲什麼componentDidUpdate看不到新插入的dom節點?

var Hello = React.createClass({ 
    getInitialState() { 
    return {content: '<div id="target">ciao!</div>'} 
    }, 

    componentDidMount() { 
    const target = $('#target').init(); 
    this.target = target; 
    }, 

    componentWillReceiveProps(nextProps) { 
    if (condition) { 
     this.target.destroy(); // this remove even the DOM node 
    } 
    }, 

    componentDidUpdate() { 
    const target = $('#target').init(); // HERE PROBLEM! can't find the #target element 
    this.target = target; 
    } 

    render: function() { 
    return <div>Hello {this.state.content}</div>; 
    } 
}); 

我不明白爲什麼後'condition'是真實和DOM節點都通過插件破壞,componentDidUpdate沒有找到#target,在我的腦海裏應該是「重新渲染」在componentWillReceiveProps之後的第一個渲染中。我希望在那裏,因爲它從最初的狀態讀取它永遠不會改變。

我錯過了什麼?

+0

你不能呈現原始的HTML一樣,不使用恰當地命名爲['dangerouslySetInnerHtml'(https://facebook.github.io/react/docs/dom-elements.html#dangerouslysetinnerhtml)。 –

+0

@JoeClay並非如此。無論如何,我試過,不改變任何東西.. – ciaoben

回答

0

在React中,您不應該在componentDidMount()生命週期方法中執行this.setState(),因爲它會導致佈局抖動。 查看更多關於佈局在這裏籌碼:https://blog.idrsolutions.com/2014/08/beware-javascript-layout-thrashing/

原因是,this.setState()導致重新呈現(調用render()兩次)。而這在實際的渲染方法發生一次在componentDidMount()一次。你應該找到一個方法來消除從componentDidMountsetState()和你的問題可能得到解決。作爲初始嘗試,我會將this.setState()移動到componentWillMount()方法內

+0

是的,你的權利,其實我沒有使用的setState,但「此」對象settig模式,我將改寫例子!無論如何,這不是問題 – ciaoben

+0

你的'componentDidMount()'中的'this.setState({target:target})'如何?嘗試移動'componentWillMount()' –

+0

mmmm內部我認爲你不清楚問題。如果我將它移動到WillMount的DOM節點不在那裏,所以我不能綁定任何jQuery插件 – ciaoben

1

由於您正在使用jQuery操作react元素(this.state.content),這使得React無法檢測到呈現內容的更改。所以,當你渲染它第一次

  1. componentDidUpdate具有初始狀態,完全呈現組件,包括#target
  2. $('#target').init()之後被調用時,渲染組件外部更改,恕不通知做出反應
  3. $('#target').destroy()被調用時,#target節點被從DOM中刪除而不通知React
  4. 因此,當您在componentDidUpdate中調用$('#target').init()時,您無法找到#target因爲反應。在#target沒有檢測到任何變化,由於該陣營不會選擇重新渲染這個事實#target不會再生。

所以一兩件事你可以做的是更新componentWillReceiveProps狀態(in condition check),注意data-updated領域,這將確保陣營檢測爲this.state.content的狀態變化,因此將重新呈現組件,您將在componentDidUpdate

componentWillReceiveProps(nextProps) { 
    if (condition) { 
    this.target.destroy(); // this remove even the DOM node 
    this.state.content = `<div id="target" data-updated="${Date.now()}">ciao!</div>`; 
    } 
} 

鑑於這一發現再次#target,我建議你看看refs的反應。

+0

你的答案有很多道理!稍後在工作中,我會試着讓你知道。我知道裁判,但由於我已經「繞過」反應與jQuery在這casa我沒有看到使用$選擇器的問題..你認爲是更好的使用裁判? – ciaoben

+0

使用方式沒有太大的區別,但其中一個參數可能是$('#target')在DOM中找到所有內容(如果有其他'#target',也可能會影響性能)。相反,$(this.refs.target)使得這個jQuery選擇器非常有效。 –

+0

謝謝...我試過你的解決方案,但沒有工作......它沒有任何意義......不能理解爲什麼不通過反應重新呈現,即使是與屬性不同 – ciaoben

相關問題