材料表类型错误:无法添加属性表数据,对象不可扩展
Posted
技术标签:
【中文标题】材料表类型错误:无法添加属性表数据,对象不可扩展【英文标题】:Material-table TypeError: Cannot add property tableData, object is not extensible 【发布时间】:2020-04-26 03:23:41 【问题描述】:我正在使用 meterial-table
和 React
。我正在尝试从来自这样的 api 的数组中分配数据
<MaterialTable
columns=columns
data=rows
...
/>
其中columns
和rows
是api 数据。但是我收到了这个错误:
TypeError: Cannot add property tableData, object is not extensible
值得注意的是,当我使用模拟硬编码数据时,一切正常。经过一番搜索,我找不到任何解决方案,有什么帮助吗?
【问题讨论】:
github.com/apollographql/react-apollo/issues/1251 相关:***.com/questions/55567386/… - 和 developer.mozilla.org/en-US/docs/Web/javascript/Reference/… ,在我使用 redux 实现材料表时发现了这个线程,它在我的故事书故事中工作,因为我直接使用模拟数据,但在开发中我通过 redux 存储使用模拟数据并得到相同的错误。 【参考方案1】:您很可能使用immer
或在后台使用immer
的库(例如@reduxjs/toolkit
)。 immer
使用 Object.freeze
使其生成的对象不可变。
material-table
修改自己的 props(这是一个非常丑陋的反模式)。当图书馆违反规则时,它们不会与试图强制执行规则的图书馆合作。
无法解冻已冻结的对象,但您有几个选择:
找到一种在 immer 实例中禁用冻结的方法(查看 API 文档,了解您认为可能冻结了您的状态的任何内容)。
覆盖 Object.freeze
让它什么都不做(非常hacky,应该避免 - 但它可能是你最好的选择):
window.Object.freeze = function(obj) return obj
-
在将状态传递给
MaterialTable
之前克隆/深度复制您的状态。这也远非理想,尤其是在您拥有大量数据的情况下。
【讨论】:
非常感谢您的建议/解释。我在使用immer
时遇到了完全相同的问题。值得庆幸的是,immer
确实提供了禁用冻结的功能:import setAutoFreeze from 'immer'; setAutoFreeze(false);
【参考方案2】:
这与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)
,因为这将复制具有相同对象引用的数组
编辑:
值得一提的是,使用 spread operator 或 Object.assign 只会给出浅拷贝,即不会拷贝嵌套对象。一种解决方法是使用JSON.parse(JSON.stringify(object))
。请注意,这会导致一些数据丢失,这个答案还有其他选择:
What is the most efficient way to deep clone an object in JavaScript?
【讨论】:
值得注意的是,如果使用这种方法,“你只会得到浅拷贝”,它可能是你想要的,也可能不是 =) 2ality.com/2016/10/…【参考方案3】:从 'immer' 导入 setAutoFreeze ; setAutoFreeze(false);
为我工作。 材质表应该考虑一个和immer很好玩的api
【讨论】:
谢谢。如果使用 Redux Toolkit,你怎么称呼它? 您在全局范围内或在开始使用 immer 之前将 AutoFreeze 设置为 false【参考方案4】:在Material Data Table
中传递数组数据时出现此错误
我用的是reduxjs/toolkit
由于对象不可修改,由于Object.freeze()
by 的内部实现
reduxjs/工具包
const cycleList=JSON.parse(JSON.stringify(useSelector(state=>state.cycleSlice)));
我使用上述方法创建了对象的新副本。
【讨论】:
以上是关于材料表类型错误:无法添加属性表数据,对象不可扩展的主要内容,如果未能解决你的问题,请参考以下文章