Реагировать на редактирование таблицы материалов из реквизита, используя крючки - PullRequest
2 голосов
/ 30 марта 2020

Я создаю приложение, которое будет запрашивать данные у API и отображать их в редактируемой таблице, где пользователь может редактировать и обновлять базу данных. Я использую React с material-ui и material-table.

Я инициализирую данные в состоянии родительского компонента и передаю их как реквизиты дочернему компоненту, который отображает таблицу. В целях тестирования я инициализирую данные в состоянии для имитации последующей реализации реквизита. Таблица отображается правильно, но при редактировании значения не меняются.

export default function Table(props){
  const [gridData, setGridData] = useState({
    data: [
      { param: "Admin", val: "0.03" },
      { param: "Margin", val: "0.4" },
      { param: "Price", val: "5080" },
    ],
    resolve: () => {}
  });
  useEffect(() => {
    gridData.resolve();
  }, [gridData]);

  const onRowUpdate = (newData, oldData) =>
    new Promise((resolve, reject) => {
      const { data } = gridData;
      const index = data.indexOf(oldData);
      data[index] = newData;
      setGridData({ ...gridData, data, resolve });
    });

  const { data } = gridData;
  return (
    <div>
      <MaterialTable
      columns={props.col}
      data={data}
      editable={{
        isEditable: rowData => true,
        isDeletable: rowData => true,
        onRowUpdate: onRowUpdate
      }}
      />
    </div>
  );
}

Теперь я обнаружил, что таблица работает правильно, когда я заменяю строку columns={props.col} на эту:

columns={[
        { title: 'Parameters', field: 'param', editable: 'never' },
        { title: 'Value', field: 'val', editable: 'onUpdate' }
      ]}

Так что, похоже, моя проблема с колонками, а не с данными.

Любая помощь будет принята с благодарностью!

ПРИМЕЧАНИЕ: код основан на ответе github: https://github.com/mbrn/material-table/issues/1325

РЕДАКТИРОВАТЬ: Столбцы передаются из родительского компонента, как это:

const comonscol = [
  { title: 'Parameters', field: 'param', editable: 'never' },
  { title: 'Value', field: 'val', editable: 'onUpdate' }
];

export default function ParamsSection(props) {
    ...
    return (
        <div>
            ...
            <Table col={comonscol} data={dummy2} />
            ... 
        </div>
    );
}

1 Ответ

1 голос
/ 31 марта 2020

Я не совсем уверен относительно причины этой проблемы, но кажется, что компонент MaterialTable не вызывает повторную визуализацию , когда данные столбцов передаются как porps.

Вот как я это исправил:

Первый подход:

Создайте новый state для столбцов и запустите повторную визуализацию, обновив столбцы с помощью useEffect:

const [gridData, setGridData] = useState(props.data);
const [columns, setcolumns] = useState(props.col);

useEffect(() => {
  gridData.resolve();

  // update columns from props
  setcolumns(props.col);
}, [gridData, props.col]);

...

const onRowUpdate = (newData, oldData) =>
  new Promise((resolve, reject) => {
    // Reset the columns will trigger re-render as the state has changed 
    // then it will update by useEffect
    setcolumns([]);
    const { data } = gridData;
    const updatedAt = new Date();
    const index = data.indexOf(oldData);
    data[index] = newData;
    setGridData({ ...gridData, data, resolve, updatedAt });
});

codeSandbox Пример.


Второй подход:

Слияние data, columns в состояние объект и сделать копию реквизита данных затем использовать эту копию. (Я немного изменил структуру даты для тестирования)

// Parent
const data = [
  { param: "Admin", val: "0.03" },
  { param: "Margin", val: "0.4" },
  { param: "Price", val: "5080" }
];
const comonscol = [
  { title: "Parameters", field: "param" },
  { title: "Value", field: "val" }
];

... 

<Table col={comonscol} data={data} />


// Table.js
const [gridData, setGridData] = useState({
  data: props.data,
  columns: props.col,
  resolve: () => {},
  updatedAt: new Date()
});

const onRowUpdate = (newData, oldData) =>
  new Promise((resolve, reject) => {
    // Copy current state data to a new array
    const data = [...gridData.data];
    // Get edited row index
    const index = data.indexOf(oldData);
    // replace old row
    data[index] = newData;
    // update state with the new array
    const updatedAt = new Date();
    setGridData({ ...gridData, data, updatedAt, resolve });
});

codeSandbox Пример.


Примечание: onRowUpdate здесь в качестве примера, То же самое касается onRowAdd, onRowDelete

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...