[英]Update dynamic created components
我有一個父組件,它呈現一些子組件。 子組件應顯示從父組件傳遞的信息。
與多人游戲的戰艦游戲:
父組件包含10x10到10x30按鈕(子組件)的字段。 如果按下按鈕,則具有按鈕位置的信號將被發射到api。 api決定按下的按鈕是否需要改變它的顏色。
通過更新父級的狀態,如果動態創建子級,則不會更新子組件props。
在我的情況下不可能
我認為孩子是轉儲/表示組件,因為它只顯示信息。 在我的情況下,還有100-300個子組件。 Redux和React
有100-300個兒童組件... 不要過度使用參考
我該怎么辦? 有沒有反模式的解決方案?
現行守則
class Parent extends React.Component { constructor(props) { super(props); this.state={ foo: 'BAR' } this.child=undefined; } componentWillMount(){ this.child=<Child foo={this.state.foo}/> } componentDidMount(){ var that=this setTimeout(function(){ that.setState({ //it is just here for demonstration foo: 'FOO' }) }, 1000); } render() { return ( <div> Is: {this.child} Not Dynamic created: <Child foo={this.state.foo}/> Actual: <p>{this.state.foo}</p> </div> ); } } class Child extends React.Component { render() { return ( <p>{this.props.foo}</p> ); } } ReactDOM.render(<Parent />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="app"></div>
代碼來自@RaghavGarg和@Clinton Blackburn
class Parent extends React.Component { constructor(props) { super(props); this.state={ foo: 'BAR' } this.child=undefined; } componentDidMount(){ var that=this setTimeout(function(){ that.setState({ //it is just here for demonstration foo: 'FOO' }) }, 1000); } renderChild(){ return <Child foo={this.state.foo} /> } render() { const child=this.renderChild() return ( <div> Is: {child} Not Dynamic created: <Child foo={this.state.foo}/> Actual: <p>{this.state.foo}</p> </div> ); } } class Child extends React.Component { render() { return ( <p>{this.props.foo}</p> ); } } ReactDOM.render(<Parent />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='app'/>
就像@Clinton所說的那樣, componentWillMount
只會調用一次。 因此,您實際上是在啟動this.child
變量,但只更新狀態,還需要更新變量的值。
因為您只是制作動態組件並將它們保存在類實例中(如this.child
)。 我建議你在componentWillUpdate
執行相同的任務。 因此,無論何時狀態發生變化,它都會反映在您的因變量中。 但請確保不要在此生命周期方法中使用setState
。
在接收新的道具或狀態時,在渲染之前調用
componentWillUpdate()
。 使用此作為在更新發生之前執行准備的機會。
另外,請考慮使用構造函數來啟動狀態,而不是在componentWillMount
使用setState
。
在安裝發生之前調用
componentWillMount()
。 它在render()
之前調用,因此在此方法中同步調用setState()
不會觸發額外的渲染。 通常,我們建議使用constructor()
來初始化狀態。
參考:
https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
所以現在,我假設您將在維持每個框(子組件)狀態的狀態下擁有DS(可能是對象或嵌套數組)。 你可以遍歷它並為它們中的每一個提供一個唯一的key
(可能像{row}-{col}
),現在你只需要更新狀態以反映特定子項的變化。
注意:對每個子項使用唯一鍵將啟用react內部優化重新呈現,並且不會重新呈現子項(使用唯一鍵),這不會更改。 請參閱以下代碼以供參考。
this.state = {
boxes: {
1: {
1:{ status: true, /* more data */ },
2:{ status: true, /* more data */ },
},
2: {
1:{ status: true, /* more data */ },
2:{ status: true, /* more data */ },
},
3: {
1:{ status: true, /* more data */ },
2:{ status: true, /* more data */ },
},
4: {
1:{ status: true, /* more data */ },
2:{ status: true, /* more data */ },
}
}
};
// this will create a 4x2 box, now you will render using above object
// ...somewhere in your render method
{
Object.keys(this.state.boxes).map(row => (
<div key={`row-${row}`} className="row">
{
Object.keys(this.state.boxes[row]).map(column => (
<Child
key={`box-${row}x${column}`}
data={this.state.boxes[row][column]}
/>
))
}
</div>
))
}
現在,每當您將2x1
框的status
更改為false
,react將僅使用密鑰box-2x1
重新呈現子項。
應該使用shouldComponentUpdate
來決定是否要在狀態更改時更新組件。 它是React組件的生命周期方法。 默認情況下,它返回true
,但您可以根據條件返回false
基礎,以便不更新組件。 這肯定有助於保持良好的表現。
componentWillMount
僅在將父組件插入DOM時調用一次。 可能不是您想要創建安裝后需要更改的子組件的位置。 請參閱https://reactjs.org/docs/react-component.html#the-component-lifecycle上的組件生命周期。
最簡單的解決方案是在render()
方法中創建子組件。 更新父組件時將重新創建子組件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.