Компонент «Таблица реакции-табулятора» выдает ошибку при передаче данных по состоянию редукции

У меня возникли проблемы с библиотекой react-tabulator в ReactJS. когда я пытаюсь использовать компонент ReactTabulator и передать значение реквизита data (которое мне нужно получить из хранилища Redux), компонент выдает ошибку («MachineID» доступен только для чтения) [Подробнее см. ScreenShot]. Я также попробовал табличный компонент TanStack, и он работает отлично, поэтому я не уверен, что здесь делаю не так!

Библиотеки Редукса:

"react-redux": "^9.1.0"
"redux": "^5.0.1"
"@reduxjs/toolkit": "^2.2.1"

Мой код:

import * as React from "react";

import { useSelector } from "react-redux";

import "react-tabulator/lib/styles.css"; // required styles
import "react-tabulator/lib/css/tabulator.min.css"; // theme
import { ReactTabulator } from "react-tabulator";
import { useEffect, useState } from "react";

const CostSheet = () => {
  // TRY ONE
  const { basic_costsheet } = useSelector((state) => state.qm.costsheet);

  // TRY TWO
  const [data, setData] = useState(basic_costsheet);

  // TRY THREE
  const mod_arr = basic_costsheet.map((e) => e);

  // TRY FOUR
  const mod_arr_two = [];
  basic_costsheet.forEach((element) => {
    mod_arr_two.push(element);
  });

  // TRY FIVE
  const cs_data = [
    {
      McID: 1,
      MachineID: "1",
      MachineName: "m1",
      MaxLength: 1020,
    },
    {
      McID: 2,
      MachineID: "2",
      MachineName: "m2",
      MaxLength: 1050,
    },
    {
      McID: 3,
      MachineID: "3",
      MachineName: "m3",
      MaxLength: 1050,
    },
    {
      McID: 4,
      MachineID: "41",
      MachineName: "m4",
      MaxLength: 1060,
    },
  ];

  const columns = [
    { title: "MachineID", field: "MachineID" },
    { title: "MachineName", field: "MachineName" },
    { title: "MaxLength", field: "MaxLength" },
  ];

  const options = {
    layout: "fitColumns",
    pagination: "local",
    paginationSize: 10,
    movableColumns: true,
    resizableRows: true,
    initialSort: [{ column: "MachineID", dir: "asc" }],
  };

  return (
    <div>
      <ReactTabulator
        columns = {columns}
        data = {basic_costsheet} // TRY FIVE works as i pass static data or set data directly in useState.
        options = {options}
      />

      {/* Every variable/state/redux state gets printed perfectly so the data is loading (IF AVAILALBE). no issues on that front! */}
      <pre>{String(JSON.stringify(basic_costsheet))}</pre>
      <pre>{String(JSON.stringify(data))}</pre>
      <pre>{String(JSON.stringify(mod_arr))}</pre>
      <pre>{String(JSON.stringify(mod_arr_two))}</pre>
      <pre>{String(JSON.stringify(cs_data))}</pre>
    </div>[![][1]][1]
  );
};

export default CostSheet;

🤔 А знаете ли вы, что...
React поддерживает создание контекста для передачи данных между компонентами.


62
1

Ответ:

Решено

Похоже, проблема в том, что ReactTabulator каким-то образом изменяет объекты массива data, и это нарушается при использовании значений непосредственно из хранилища, созданного Redux-Toolkit (RTK). Это связано с тем, что RTK использует Immer.js под капотом и обеспечивает, чтобы выбранное состояние было доступно только для чтения. Другими словами, чтобы вы не выстрелили себе в ногу, изменив состояние.

Однако вы можете просто создать новые ссылки на объекты данных, которые не связаны напрямую со значениями вашего Магазина. Мелко скопируйте массив basic_costsheet и мелко скопируйте каждый элемент массива.

Примеры:

const { basic_costsheet } = useSelector((state) => state.qm.costsheet);

...

<ReactTabulator
  columns = {columns}
  data = {basic_costsheet.map(item => ({ ...item }))}
  options = {options}
/>
const basic_costsheet = useSelector((state) => state.qm.costsheet
  .basic_costsheet
  .map(item => ({ ...item }))
);

...

<ReactTabulator
  columns = {columns}
  data = {basic_costsheet}
  options = {options}
/>