我有一个父组件,它呈现一些子组件。 子组件应显示从父组件传递的信息。
与多人游戏的战舰游戏:
父组件包含10x10到10x30按钮(子组件)的字段。如果按下按钮,则具有按钮位置的信号将被发射到api。 api决定按下的按钮是否需要改变它的颜色。
通过更新父级的状态,如果动态创建子级,子组件props将不会更新。
在我的情况下不可能
我将子视为dump / presentational Component,因为它只显示信息。在我的情况下,还有100-300个子组件。 Redux and React
有100-300个子组件...... Don’t Overuse Refs
我该怎么办?有没有反模式的解决方案?
现行守则
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'));
&#13;
<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>
&#13;
来自@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'));
&#13;
<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'/>
&#13;
答案 0 :(得分:2)
就像@Clinton所说,componentWillMount
只会被调用一次。所以你基本上是在发起你的this.child
变量,但只是更新状态,你还需要更新变量的值。
由于您只是制作动态组件并将其保存在类实例中(如this.child
)。我建议您在componentWillUpdate
中执行相同的任务。因此,无论何时状态发生变化,它都会反映在您的因变量中。但请确保不要在此生命周期方法中使用setState
。
在渲染新道具之前调用
componentWillUpdate()
或正在收到国家。以此为契机 更新发生前的准备工作。
另外,请考虑使用构造函数来启动状态,而不是在setState
中使用componentWillMount
。
在安装发生之前调用
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}
),现在你只需要更新状态以反映特定孩子的变化。
注意:使用每个子项的唯一键将启用内部优化重新呈现,并且不会重新呈现子项(使用唯一键),这不会更改。请参阅以下代码以供参考。
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>
))
}
现在,每当您将status
2x1
false
框更改为box-2x1
时,反应将仅使用密钥shouldComponentUpdate
重新呈现该儿童。
true
来决定是否要在状态更改时更新组件。它是React组件的生命周期方法。默认情况下,它返回false
,但您可以根据条件返回Class Game:
def __init__():
points = 0
self.hidden_password = []
self.hidden_password2 = []
self.country = ""
self.used = []
self.start_time = datetime.now()
self.welcome() # This should be in main function
self.choice() # This should be in main function
def choice(self, ...):
pass
def welcome(self, ...):
pass
def guessing_capital(self, ...):
pass
def checking_password(self, ...):
pass
以不更新组件。这肯定有助于保持良好的表现。
参考: React: Parent component re-renders all children, even those that haven't changed on state change
答案 1 :(得分:1)
componentWillMount
仅在将父组件插入DOM时调用一次。可能不是您想要创建安装后需要更改的子组件的位置。
请参阅https://reactjs.org/docs/react-component.html#the-component-lifecycle处的组件生命周期。
最简单的解决方案是在render()
方法中创建子组件。更新父组件时将重新创建子组件。