材料表类型错误:无法添加属性表数据,对象不可扩展

Posted

技术标签:

【中文标题】材料表类型错误:无法添加属性表数据,对象不可扩展【英文标题】:Material-table TypeError: Cannot add property tableData, object is not extensible 【发布时间】:2020-04-26 03:23:41 【问题描述】:

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

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

其中columnsrows 是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-tableReact 无关。这很可能与您的 api 响应有关,出于某种原因在其上应用了 Object.preventExtensions(),也许这是 Axios 行为。所以当material-table 试图向每个对象添加一个id 字段时,它就会面临这个错误。 虽然不是最佳的,但尝试将您的 api 数据复制到新的对象数组中,以便 material-table 可以修改它们,例如:

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

请注意,我没有使用rows.map(o =&gt; o),因为这将复制具有相同对象引用的数组

编辑: 值得一提的是,使用 spread operatorObject.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))); 

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

【讨论】:

以上是关于材料表类型错误:无法添加属性表数据,对象不可扩展的主要内容,如果未能解决你的问题,请参考以下文章

角材料表类型错误:无法读取未定义的属性“汽车”

反应:无法添加属性'X',对象不可扩展

如何使用角材料在具有可扩展行的表中创建嵌套垫表

EXCEL 数据透视表 不可读取

代码在 codeSandbox 中运行良好,但在 IDE 中显示错误为“无法定义属性“电子邮件”:对象不可扩展”

cass怎么给实体添加属性