在React状态下合并对象

时间:2020-02-05 07:59:57

标签: reactjs react-hooks

我正在实时接收新的数据点,并且正在尝试使用react useState钩子来更新我的数据。可能有数十万个点,因此更新必须高效。我的状态结构大致如下:

{
  "graph1": {
    "line1": [[x1, y1], [x2, y2],..., [x100, y100]],
    "line2": [[x1, y1], [x2, y2],..., [x200, y200]],
    "line3": [[x1, y1], [x2, y2],..., [x900, y900]]
  },
  "graph2": {
    "line1": [[x1, y1], [x2, y2],..., [x100, y100]],
    "line2": [[x1, y1], [x2, y2],..., [x200, y200]]
  }
}

xi, yi只是浮点数。我收到类似格式的更新,例如:

{
  "graph1": {
    "line1": [[x101, y101]],
    "line3": [[x901, y901], [x902, y902]],
    "line4": [[x1, y1]],
  },
  "graph2": {
    "line1": [[x101, y101]],
  }
}

我想更新我的状态,使其看起来像这样:

{
  "graph1": {
    "line1": [[x1, y1], [x2, y2],..., [x101, y101]],
    "line2": [[x1, y1], [x2, y2],..., [x200, y200]],
    "line3": [[x1, y1], [x2, y2],..., [x902, y902]],
    "line4": [[x1, y1]]
  },
  "graph2": {
    "line1": [[x1, y1], [x2, y2],..., [x101, y101]],
    "line2": [[x1, y1], [x2, y2],...,  [x200, y200]]
  }
}

有没有比一堆散布操作员更简单的方法?即

setGraphs(xs => ({
  ...xs,
  "graph1": {
    ...xs.graph1,
    "line1": [...xs.graph1.line1, ...new_data.graph1.line1],
    // etc
})

特别是,使用散布运算符方法时,我不清楚如何处理一组动态键-例如,上述更新中的新"line4"键。

我对数据的结构和我的React代码的结构都有完全的控制权,因此,如果有一种惯用的方式来实现相同的目标,我也很乐意听到。

2 个答案:

答案 0 :(得分:2)

您可以重新生成状态并将其重置。您的解决方案仅在您知道所有可能的键时才起作用,否则,我们需要通过迭代来合并它们。像这样:

setGraph(graph => {
  Object.keys(newData).forEach(g => {
    Object.keys(newData[g]).forEach(l => {
      if (graph[g][l]) {
        graph[g][l] = [...graph[g][l], ...newData[g][l]);
      } else {
        graph[g][l] = newData[g][l];
      }
    });
  });
  return graph;
});

答案 1 :(得分:0)

Spread运算符是更新对象或数组的最佳方法。 ECMA Script 2015及更高版本中的新功能之一。