将新项目添加到数组的开头时,我遇到了有线问题
签出示例
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {arr: [{title: 3}, {title: 2}, {title: 1}]};
}
render() {
return <div>
{
this.state.arr.map((item, index) => <Element title={item.title} isNew={item.isNew}
key={index}/>
)}
<button onClick={() => {
const arr = [...this.state.arr];
const newItem = this.state.arr.length + 1;
arr.unshift({title: newItem, isNew: true});
this.setState({arr: arr});
}}>ADD ELEMENT TO START
</button>
</div>
}
}
class Element extends React.Component {
constructor(props) {
super(props);
console.log('constructor : ', this.props.title);
}
componentDidMount() {
console.log('componentDidMount : ', this.props.title);
}
render() {
return <span style={{padding : '0 8px' , color: this.props.isNew ? 'red' : 'black'}}>{this.props.title}</span>
}
}
ReactDOM.render(<Demo/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
在将新项目添加到数组的开头时签出 log ,它显示数组最后一项的道具,而不是第一个道具(因为我们将项目添加到开头)
我正在根据需要更改状态,渲染是正确的,但错误的组件(最后一个组件)的构造函数被调用的情况与componentDidMount
相同。
将项目添加到数组末尾时,该应用程序将完美运行,但并非相反。
答案 0 :(得分:2)
看起来像在React中滥用key
。
您的<Element key={index} ... />
代码使用state.arr
数组的索引来键入您的项目,React使用key
来确定是否有任何更改。
当您在开始处添加一个项目时,新项目将被分配给键0
,该键已经存在于旧项目列表中,因此React不会发现任何差异,并且不会更新前三个元素。在第四个元素上,它将尝试呈现新元素,但是数组中的第四件事实际上是原始数组的最后一个元素。
尝试在对象的唯一部分上建立索引,例如title
之类的东西,因此React可以正确找出何时更新内容。