ReactJS:组件列表的呈现不正确
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactJS:组件列表的呈现不正确相关的知识,希望对你有一定的参考价值。
我有一个组件(“ComponentA”)在另一个组件(“ComponentB”)的render()内的map()中多次呈现。
此外,我在ComponentB中有一个“ADD”按钮,当它被点击时,在其ComponentB的“state.objects”数组(用于映射ComponentA的实例)中预先挂起(通过'unshift()方法)一个对象。每个前置对象都有一个属性'prop1',我用它设置ComponentA的输入文本值。
问题是我没有在ComponentA的每个实例的状态中得到期望的值:在所有情况下,元素总是具有值'1'(我期望... 3,2,1)。
更重要的是,我看到ComponentA的构造函数只在每个映射循环中调用一次,特别是在最后一个实例的render()调用之前。
这是(简化)代码:
class ComponentB extends Component {
constructor(props) {
super(props) // added upon first reply
this.handleObjectAdd = this.handleObject.bind(this);
this.state.objects = [];
}
handleObjectAdd() {
this.state.objects.unshift({prop1: this.state.objects.length + 1});
}
render() {
return (
<div>
<button onClick={this.handleObjectAdd}>ADD</button>
{ this.state.objects.map((object, index) =>
<ComponentA key={index} details={object}/>
)
}
</div>
)
})
}
}
class ComponentA extends Component {
constructor(props) {
super(props) // added upon first reply
console.log('ComponentA constructor called');
this.state = { details: props.details };
}
render() {
console.log('ComponentA render() called, prop1 value is ' + this.state.details.prop1);
return (
<input type="text" value={this.state.details.prop1}></input>
)
}
}
因此,使用上面的代码,单击ADD按钮一次会记录以下内容:
ComponentA constructor called
ComponentA render() called, prop1 value is 1
点击第二次按钮记录:
ComponentA render() called, prop1 value is 1
ComponentA constructor called'
ComponentA render() called, prop1 value is 1
点击按钮第3次日志:
ComponentA render() called, prop1 value is 1
ComponentA render() called, prop1 value is 1
ComponentA constructor called'
ComponentA render() called, prop1 value is 1
... 等等。
在ComponentA的所有实例中,输入文本值为“1”。
我的问题是:
1)如何对其进行编码以获得为ComponentA提供的所需增加值?
2)为什么映射组件的构造函数只调用一次,并且在该特定位置(就在最后一个渲染实例之前)?
注意:上面的代码只是我实际代码的简化版本,仅显示了演示该问题的基本部分。
你should never mutate the state directly通过像this.state.objects.unshift()
这样的东西 - 使用this.setState()
代替。当您直接修改this.state
中的数组或对象时,React不知道其中的某些值已更改。这回答了你的问题。因此,而不是直接修改this.state.objects
:
this.state.objects.unshift({prop1: this.state.objects.length + 1});
您应该以不可变的方式将新项目添加到数组中:
const newItem = { prop1: this.state.objects.length + 1 };
this.setState({
objects: [newItem].concat(this.state.objects)
});
除此之外,你忘了在super(props)
和ComponentA
的构造者中调用ComponentB
。此外,没有必要将传递的道具复制到ComponentA
内的组件状态 - 只需使用道具。你可以看到工作代码盒here。
问题的解决方法来自使用此代码:
<input value={this.props....} onChange={...} // first version
代替
<input value={this.state....} onChange={....} // second version
我以前认为第二个版本是正确的,第一个版本阻止输入可编辑。但似乎onChange上的存在使第一个版本工作(正确显示初始值和编辑值并允许编辑)
以上是关于ReactJS:组件列表的呈现不正确的主要内容,如果未能解决你的问题,请参考以下文章