[英]Material-table TypeError: Cannot add property tableData, object is not extensible
我正在使用带有React
meterial-table
。 我正在尝试从来自这样的 api 的数组中分配数据
<MaterialTable
columns={columns}
data={rows}
...
/>
其中columns
和rows
是 api 数据。 但我收到了这个错误:
TypeError: Cannot add property tableData, object is not extensible
值得注意的是,当我使用模拟硬编码数据时,一切正常。 经过一番搜索,我找不到任何解决方案,有什么帮助吗?
您很可能使用immer
或在后台使用immer
的库(例如@reduxjs/toolkit
)。 immer
使用Object.freeze
使其生成的对象不可变。
material-table
修改了自己的 props(这是一个非常丑陋的反模式)。 当图书馆违反规则时,它们不会与试图强制执行规则的图书馆合作。
无法解冻已冻结的对象,但您有几个选择:
找到一种在 immer 实例中禁用冻结的方法(查看 API 文档,了解您认为可能冻结了您的状态的任何内容)。
覆盖Object.freeze
使其什么都不做(非常hacky,应该避免 - 但它可能是你最好的选择):
window.Object.freeze = function(obj) { return obj }
MaterialTable
之前克隆/深度复制您的状态。 这也远非理想,尤其是在您拥有大量数据的情况下。这与material-table
或React
无关。 这很可能与您的 api 响应有关,出于某种原因在其上应用了Object.preventExtensions()
,也许这是Axios
行为。 因此,当material-table
尝试为每个对象添加一个id
字段时,它会遇到此错误。 虽然不是最佳的,但尝试将您的 api 数据复制到一个新的对象数组中,以便material-table
可以修改它们,例如:
const editable = rows.map(o => ({ ...o }));
<MaterialTable
columns={columns}
data={editable}
...
/>
请注意,我没有使用
rows.map(o => o)
因为这将复制具有相同对象引用的数组
编辑:值得一提的是,使用扩展运算符或Object.assign只会给出浅拷贝,即不会复制嵌套对象。 一种解决方法是使用JSON.parse(JSON.stringify(object))
。 请注意,这会导致一些数据丢失,其他替代方法在这个答案上: What is the most effective way to deep clone an object in JavaScript?
从“immer”导入 { setAutoFreeze }; 设置自动冻结(假);
为我工作。 材质表应该考虑一个和immer配合得很好的api
在我使用reduxjs/toolkit
的Material Data Table
中传递数组数据时出现此错误
由于对象是不可修改的,由于Object.freeze()
的内部实现
reduxjs/工具包
const {cycleList}=JSON.parse(JSON.stringify(useSelector(state=>state.cycleSlice)));
我使用上述方法来创建对象的新副本。
就我而言,使用“structuredClone”功能解决了同样的问题。
var a = useSelector((state) =>state.cusLocChartTable.CusLocationCT);
const cloneData = structuredClone(a.billcity_table);
<ThemeProvider theme={defaultMaterialTheme}>
<MaterialTable
columns={[
{ title: 'City', field: 'city' },
{ title: 'Customers', field: 'customers' }
]}
data={cloneData}
title="Customers"
/>
</ThemeProvider>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.