Material-table TypeError: Cannot add property tableData, object is not extensible
Material-table TypeError: Cannot add property tableData, object is not extensible
我正在使用 meterial-table
和 React
。我正在尝试从来自 api 的数组中分配数据,就像这样
<MaterialTable
columns={columns}
data={rows}
...
/>
其中 columns
和 rows
是 api 数据。但我收到此错误:
TypeError: Cannot add property tableData, object is not extensible
值得注意的是,当我使用模拟硬编码数据时,一切正常。经过一番搜索,我找不到任何解决方案,有帮助吗?
这与material-table
或React
无关。这很可能与您的 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
修改自己的道具(这是一个非常丑陋的反模式)。当图书馆违反规则时,他们将不会与试图强制执行这些规则的图书馆合作。
无法解冻已冻结的对象,但您有两种选择:
找到一种在 immer 实例中禁用冻结的方法(查看 API 文档,了解您认为可能冻结您的状态的任何内容)。
覆盖 Object.freeze
使其无所事事(非常 hacky,应该避免 - 但它可能是你最好的选择):
window.Object.freeze = function(obj) { return obj }
- 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)));
我用上面的方法创建了对象的新副本。
我正在使用 meterial-table
和 React
。我正在尝试从来自 api 的数组中分配数据,就像这样
<MaterialTable
columns={columns}
data={rows}
...
/>
其中 columns
和 rows
是 api 数据。但我收到此错误:
TypeError: Cannot add property tableData, object is not extensible
值得注意的是,当我使用模拟硬编码数据时,一切正常。经过一番搜索,我找不到任何解决方案,有帮助吗?
这与material-table
或React
无关。这很可能与您的 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
修改自己的道具(这是一个非常丑陋的反模式)。当图书馆违反规则时,他们将不会与试图强制执行这些规则的图书馆合作。
无法解冻已冻结的对象,但您有两种选择:
找到一种在 immer 实例中禁用冻结的方法(查看 API 文档,了解您认为可能冻结您的状态的任何内容)。
覆盖
Object.freeze
使其无所事事(非常 hacky,应该避免 - 但它可能是你最好的选择):
window.Object.freeze = function(obj) { return obj }
- 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)));
我用上面的方法创建了对象的新副本。