对象数组上的React setState重新呈现每个组件

时间:2017-12-12 19:26:41

标签: reactjs

我正在使用React,并希望更新状态中的对象数组。互联网的总体答案是使用类似的方法:

const newState = this.state.elements.slice().concat({key: 'val'});
this.setState({elements: newState});

但是我遇到的问题是,当这些数据绑定到渲染函数和组件时,它会重新渲染每个组件。

示例include(映射用于lodash以在映射时检索索引):

render() {
  return (
    <div>
      {map(this.state.elements, (el, index) => <Component key={`el-${index}`} el={el} />)}
    </div>
  );
}

即使数组顺序没有改变,组件的关键字也没有改变,每次状态改变时,它都会从头开始重新渲染和安装组件。

这个问题是否有可行的最佳实践解决方案?

最佳, ÿ

1 个答案:

答案 0 :(得分:3)

发生的事情是,当您调用setState时,React Virtual Dom会传播状态并再次调用渲染。渲染调用Map函数,该函数渲染每个组件。由于父组件发生更改,因此每个组件都会被丢弃并重新绘制。

这是React的正常和预期行为。它正在做你所要求的,你改变状态,它重绘组件。

但是你的问题是如何在没有重绘的情况下将我的新组件附加到组件列表中?

我认为问题在于你依赖于react的唯一键作为数组项的索引。

<Component key={`el-${index}`}  

每次更新状态时都会永远改变。您需要做的是使用名称,字符串或生成的密钥或数据中的某些内容。

您只使用地图功能索引值,当然在将新元素添加到列表后会触发重新渲染,因为每个元素的键值都已更改。

如果你做了这样的事情:

<Component key={`el-${item.id}`}  

其中item id是常量但唯一的值,如数据库表中的主键。它不会重绘。密钥应具有确定性值。

有关详细信息,请参阅React Docs和其他post