2014-04-10 55 views
0

React組件包含子組件的標準方式是在渲染方法中創建它們並將其設置爲children屬性。在我的使用案例中,可能會在通過父級的屬性呈現並傳入父級之前創建子級。未在渲染中創建的Reactjs兒童不更新

按照預期,子項中的事件冒泡到父項,但對父容器的更改不會重新渲染以此方式創建的子項。 The docs表示父和關係之間存在差異,後者僅針對在渲染中創建的組件建立,所以我的猜測是這種關係對於級聯重新呈現是缺失和重要的。

下面是一個簡單的例子(fiddle

/** @jsx React.DOM */ 

globalState = 'initial state'; 

var Child = React.createClass({ 
    render: function() { 
     return React.DOM.input({ 
      value:globalState 
     }); 
    } 
}); 

var Parent = React.createClass({ 
    handleChange: function(e) { 
     globalState = e.target.value; 
     this.forceUpdate(); 
    }, 
    render: function() { 
     return React.DOM.div({ 
      children: [ 
       Child(), 
       React.DOM.br(), 
       this.props.passedChild 
      ], 
      onChange: this.handleChange 
     }); 
    } 
}); 

c = Child(); 
p = Parent({passedChild:c}); 

React.renderComponent(p, document.body); 

在該示例中,兩個子輸入可以被編輯,onChange事件由父和forceUpdate捕獲()被調用。這會級聯到在渲染方法中創建的第一個子項,但不會傳遞到在別處創建並通過的第二個子項。

如何更新子組件的所有者,以便根據需要進行更新?

我的備份計劃是連接子組件上的事件偵聽器。在我的應用程序中,創建組件時會有相當多的邏輯,這會使render()中的所有操作都變得不切實際。

回答

2

這裏有點複雜的解釋,但是你的代碼現在可以在React的主版本(post 0.10.0)上工作。

我不太清楚你要在這裏完成的,但如果你改變你的this.props.passedChildthis.props.passedChild()c = Child();c = Child;,它會工作。叫它this.props.passedChildClass什麼的。您也可以嘗試this.props.passedChildFnc = function() { return Child(); }。無論你有什麼需要。

不要創建組件的實例並傳遞它(它不會很快出現問題; Child()的返回值將不再是實例)。一般來說這是不好的做法,因爲這會鼓勵突變。隨時隨地創建您的孩子,讓React處理剩下的事情。

在我的應用程序中,當創建組件時會有相當多的邏輯,這會使render()中的所有操作都變得不切實際。

將它們分解爲輔助函數!你真的不需要將所有東西都放入一個render

此外,全局狀態是一個壞主意。您的孩子通過從globalState讀取正確更新的事實非常脆弱。您必須在控制檯中收到警告(提供您正在使用的開發版本)才能添加onChange處理程序。去讀它=)。

+0

示例代碼是真實代碼的過分簡化,因此您提出的更改不是那麼簡單,但是感謝您確認這可以解決我的問題。它實際上工作在0.8.0,只有在升級到0.10.0時才被觀察到,很高興聽到該行爲回來。 –