gpt4 book ai didi

javascript - 更新动态创建的组件

转载 作者:行者123 更新时间:2023-11-30 11:20:52 24 4
gpt4 key购买 nike

情况

我有一个呈现一些子组件的父组件。子组件应显示从父组件传递的信息。

上下文

多人战舰游戏:

父组件包含一个 10x10 到 10x30 按钮的字段(子组件)。如果按下按钮,则会将带有按钮位置的信号发送到 api。 api 决定按下的按钮是否需要改变它的颜色。


问题

通过更新父级的状态,如果子组件是动态创建的,则子组件 Prop 将不会更新。


解决方案尝试

不要动态渲染 Childs:

在我的情况下不可能

使用redux

我认为子组件是转储/展示组件,因为它只显示信息。在我的例子中还有 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'));
<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 中执行相同的任务。这样,无论何时您的状态发生变化,它都会反射(reflect)在您的因变量中。但请确保不要在此生命周期方法中使用 setState

componentWillUpdate() is invoked just before rendering when new props or state are being received. Use this as an opportunity to perform preparation before an update occurs.

此外,考虑使用构造函数来初始化状态,而不是在 componentWillMount 中使用 setState

componentWillMount() is invoked just before mounting occurs. It is called before render(), therefore calling setState() synchronously in this method will not trigger an extra rendering. Generally, we recommend using the constructor() instead for initializing state.

引用:

https://reactjs.org/docs/react-component.html#unsafe_componentwillupdate https://reactjs.org/docs/react-component.html#unsafe_componentwillmount

添加上下文后更新

现在,我假设您将拥有一个 DS(可能是一个对象或嵌套数组),您将在其中维护每个框(子组件)的状态。您可以遍历它并为它们中的每一个提供一个唯一的 key(可能像 {row}-{col}),现在您只需要更新状态以反射(reflect)具体 child 的变化。

注意:对每个 child 使用唯一键将启用 react 内部优化重新渲染并且不会重新渲染 child (使用唯一键),这是没有改变的。请参阅下面的代码以供引用。

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>
))
}

现在,每当您将 say 2x1 框的 status 更改为 false 时,React 只会重新渲染带有键 box-2x1.

OP comment之后更新

shouldComponentUpdate 应用于决定是否要在状态更改时更新组件。它是 React 组件的一个生命周期方法。默认情况下它返回 true,但您可以根据您的条件返回 false 以不更新组件。这肯定有助于保持良好的性能。

引用: React: Parent component re-renders all children, even those that haven't changed on state change

关于javascript - 更新动态创建的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49862802/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com