处理一个巨大的状态对象

Working with a huge state object

本文关键字:巨大 状态 对象 一个 处理      更新时间:2023-09-26

我有一个在React应用程序中处理状态的问题。背景信息:该应用程序主要呈现一个包含大量数据的大表,然后可编辑这些数据。数据来自一个大对象列表的单一来源(实际上这是一个更复杂的层次结构,但为了实现这个目的,让我们保持简单),并且应该保持原样。然后,用户可以部分地更改大表中的数据,并最终保存更改。

由于数据来自单一来源,我在React中考虑并将数据存储为表状态,并将所有必要的内容传递给各个组件。因此一行只能以prop的形式获取行数据,单元格也只能以prop的形式获取单元格数据。对于单元格级别的更新过程,我使用一个反向数据流在表上调用一个更新方法,该方法更新已更新的单元格的状态:

change (rowIndex, cellIndex, value) {
    this.state.data[rowIndex][cellIndex] = value;
    this.forceUpdate();
}

这在理论上工作得很好。然而,我有很多数据;该表很容易包含大约1000行和多个列。这不是一个直接的问题:浏览器需要一些时间来呈现表格,但是一旦它在那里,它就可以很好地处理它。此外,React也没有数据量的问题。

但问题是,改变单个单元格实际上会触发整个表的呈现。即使DOM只针对单个单元格进行了更改,所有的呈现方法也会在执行时不做任何事情(因为更改只发生在单个单元格中)。

我目前的解决方案是为行组件实现shouldComponentUpdate,并对所有可变值执行深度检查,以避免在行和单元格级别的呈现。但是这感觉非常混乱,因为它不仅非常冗长,而且非常依赖于数据结构。

所以我真的不知道如何更好地解决这个问题。我目前正在考虑将状态移动到行中,以及这样的突变功能,并让表组件按需查询行中的更改。或者,我也可以将整个数据移出表,只使用标识符,然后行使用这些标识符从提供数据和提供突变功能的中央存储查询数据。这是可能的,因为整个数据在页面加载时加载一次,然后只由用户更改。

我真不知道该如何处理这种情况。我甚至在考虑为此放弃React,并将所有内容呈现为静态HTML,并在顶部添加自定义JavaScript模块,以便在请求保存时从实际输入元素中按需获取数据。有没有一种好的方法来解决这个问题?

如果你想尝试这种情况,我在CodePen上有一个运行的例子。当你输入一个输入字段时,你会注意到一个延迟,因为React调用所有的render函数,而没有真正改变DOM中的任何东西。

你应该看看PureRenderingMixin和shouldComponentUpdate文档

我对你的代码做了一些改变,所以你不直接修改状态,所以shouldComponentUpdate可以正确地比较道具,以确定是否需要渲染。这里的代码有点乱,我把它拼凑在一起真的很快,但希望它能给一个好主意,如何实现它。

http://codepen.io/anon/pen/yYXbaL?编辑= 001

  change (rowIndex, cellIndex, value) {
    this.state.data[rowIndex][cellIndex] = value;
    var newData = this.state.data.map((row, idx) => {
      if(idx != rowIndex){
        return this.state.data[idx]
      } else {
        var newRow = this.state.data[idx].map((colVal, idx) =>{
          return idx == cellIndex ? value : colVal
        })
        return newRow
      }
    });

  shouldComponentUpdate(nextProps){
    return this.props.cells != nextProps.cells;
  }