Ошибка типа таблицы материалов: невозможно добавить свойство tableData, объект не является расширяемым - PullRequest
3 голосов
/ 08 января 2020

Я использую meterial-table с React. Я пытаюсь назначить данные из массива, поступающего из API, как это

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

Где columns и rows являются данными API. Но я получаю эту ошибку:

TypeError: Cannot add property tableData, object is not extensible

Примечательно, когда я использую ложные жестко закодированные данные, все работает отлично. После некоторого поиска я не смог найти никакого решения, какую-либо помощь?

Ответы [ 2 ]

5 голосов
/ 08 января 2020

Это не имеет ничего общего с 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) поскольку это скопирует массив с теми же ссылками на объекты

EDIT : Стоит отметить, что с помощью оператора распространения или Object.assign будет давать только поверхностную копию, т.е. не будет копировать вложенные объекты. Одним из способов решения этой проблемы является использование JSON.parse(JSON.stringify(object)). Обратите внимание, что это может привести к некоторой потере данных, другие ответы на этот ответ: Какой самый эффективный способ глубокого клонирования объекта в JavaScript?

2 голосов
/ 03 мая 2020

Скорее всего, вы используете immer или библиотеку, которая использует immer под капотом (например, @reduxjs/toolkit). immer использует Object.freeze, чтобы сделать объекты, которые он производит, неизменяемыми.

material-table изменяет свой собственный реквизит (который является очень уродливым антипаттерном). Когда библиотеки нарушают правила, они не будут работать с библиотеками, которые пытаются их применить.

Нет способа разморозить замороженный объект, но у вас есть несколько вариантов:

  1. Найдите способ отключить зависание в экземпляре immer (ознакомьтесь с документацией по API того, что, по вашему мнению, могло заморозить ваше состояние).

  2. Переопределить Object.freeze заставить его ничего не делать (очень хакерский, его следует избегать - и все же это может быть вашим лучшим выстрелом здесь):

window.Object.freeze = function(obj) { return obj }
Клонируйте / глубоко копируйте свое состояние, прежде чем передать его MaterialTable. Это также далеко от идеала, особенно если у вас много данных.
...