在反应中将新项目添加到数组开始时的问题

时间:2019-06-17 17:22:51

标签: javascript reactjs

将新项目添加到数组的开头时,我遇到了有线问题

签出示例

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相同。

将项目添加到数组末尾时,该应用程序将完美运行,但并非相反。

1 个答案:

答案 0 :(得分:2)

看起来像在React中滥用key

您的<Element key={index} ... />代码使用state.arr数组的索引来键入您的项目,React使用key来确定是否有任何更改。

当您在开始处添加一个项目时,新项目将被分配给键0,该键已经存在于旧项目列表中,因此React不会发现任何差异,并且不会更新前三个元素。在第四个元素上,它将尝试呈现新元素,但是数组中的第四件事实际上是原始数组的最后一个元素。

尝试在对象的唯一部分上建立索引,例如title之类的东西,因此React可以正确找出何时更新内容。