Material-table TypeError: Cannot add property tableData, object is not extensible

Material-table TypeError: Cannot add property tableData, object is not extensible

我正在使用 meterial-tableReact。我正在尝试从来自 api 的数组中分配数据,就像这样

<MaterialTable
  columns={columns}
  data={rows}
  ...
/>

其中 columnsrows 是 api 数据。但我收到此错误:

TypeError: Cannot add property tableData, object is not extensible

值得注意的是,当我使用模拟硬编码数据时,一切正常。经过一番搜索,我找不到任何解决方案,有帮助吗?

这与material-tableReact无关。这很可能与您的 api 响应出于某种原因应用了 Object.preventExtensions() 有关,也许这是一种 Axios 行为。因此,当 material-table 尝试向每个对象添加 id 字段时,它会遇到此错误。 虽然不是最佳选择,但请尝试将您的 api 数据复制到一个新的对象数组,以便 material-table 可以修改它们,例如:

const editable = rows.map(o => ({ ...o }));
<MaterialTable
  columns={columns}
  data={editable}
  ...
/>

Note that I didn't use rows.map(o => o) as this will copy the array with the same objects references

编辑: 值得一提的是,使用展开运算符Object.assign只会给出浅拷贝,即不会拷贝嵌套对象。一种解决方法是使用 JSON.parse(JSON.stringify(object))。请注意,这会导致一些数据丢失,此答案中有其他替代方法: What is the most efficient way to deep clone an object in JavaScript?

您很可能正在使用 immer 或在后台使用 immer 的库(例如 @reduxjs/toolkit)。 immer 使用 Object.freeze 使其生成的对象不可变。

material-table 修改自己的道具(这是一个非常丑陋的反模式)。当图书馆违反规则时,他们将不会与试图强制执行这些规则的图书馆合作。

无法解冻已冻结的对象,但您有两种选择:

  1. 找到一种在 immer 实例中禁用冻结的方法(查看 API 文档,了解您认为可能冻结您的状态的任何内容)。

  2. 覆盖 Object.freeze 使其无所事事(非常 hacky,应该避免 - 但它可能是你最好的选择):

window.Object.freeze = function(obj) { return obj }
  1. Clone/deep 在将状态传递给 MaterialTable 之前复制您的状态。这也远非理想,尤其是当您有大量数据时。

从'immer'导入{setAutoFreeze}; 设置自动冻结(假);

对我有用。 material table 应该考虑与 immer

配合良好的 api

我在 Material Data Table 中传递数组数据时遇到此错误 我正在使用 reduxjs/toolkit

由于

Object.freeze() 的内部实现,对象不可修改

reduxjs/toolkit

 const {cycleList}=JSON.parse(JSON.stringify(useSelector(state=>state.cycleSlice))); 

我用上面的方法创建了对象的新副本。