Редактирование строки или состояния настройки изнутри компонента выбора - PullRequest
0 голосов
/ 08 мая 2020

У меня Dev Express Grid с EditingState и SelectionState. Общая идея состоит в том, что я хочу добавить строки, которые были либо отредактированы, либо выбраны (с помощью флажков), в переменную React.useState(), потому что я собираюсь передать этот список строк в функцию «Сохранить» веб-сервиса.

Я создал MVCE, объединив следующие две демонстрации: Редактирование и Selection , которые вы можете найти здесь:

https://codesandbox.io/s/beautiful-bhabha-p05lm?file= / demo . js

Ключевой элемент здесь:

const [updateArray, setUpdateArray] = React.useState([]);

...

function onSelectionChange(selectedRows) {
    const data = Object.assign([], rows);
    // selection is the array of previously selected rows, selectedRows are the ones now selected
    const rowsChecked = selectedRows.filter(x => !selection.includes(x));
    const rowsUnchecked = selection.filter(x => !selectedRows.includes(x));
    setSelection(selectedRows);
    rowsChecked.forEach(item => {
      const rowIndex = data.findIndex(obj => obj.id === item);
      data[rowIndex].car = "NEW CAR";
      setUpdate(true, data[rowIndex]);
    });
    rowsUnchecked.forEach(item => {
      const rowIndex = data.findIndex(obj => obj.id === item);
      data[rowIndex].car = "OLD CAR";
      if (data[rowIndex].city === "New York") {
        setUpdate(true, data[rowIndex]);
      } else {
        setUpdate(false, data[rowIndex]);
      }
    });
}

Поскольку эта setUpdate функция находится внутри компонента Selection, который находится внутри сетки, я получаю сообщение об ошибке (технически предупреждение, но вызов setUpdate не работает), что

index. js: 1 Предупреждение: невозможно обновить компонент изнутри тела функции другого компонента. в SelectionStateBase (при выборе. js: 24) *.

Если я редактирую строку или выбираю отдельную строку, кажется, что это работает, но я не могу использовать «выбрать все» функция добавления всех выбранных элементов в updateArray.

Я читал, что вы не должны синхронно вызывать setState внутри других функциональных компонентов и откладывать вызов useEffect, но у меня пробовали всевозможные комбинации React.useEffect() и React.useCallback(), но безуспешно.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 16 мая 2020

Проблема: ЧИТАТЬ

function setUpdate(isAdd, row) {

    // `updateArray` will be pointing to the old array
    const rows = Object.assign([], updateArray);
    const copy = rows.filter(i => i.name !== row.name || i.city !== row.city);
    if (isAdd) {
      copy.push(row);
    }
    console.log(JSON.stringify(copy));

    // 1. this will update updateArray asynchronously , so you wont get updated `updateArray`
    // on first line of function when its called second,third,forth ... quickly
    // which happens when you select all, it will still point to the old `updateArray`
    setUpdateArray(copy);
  }

Решение:

  function setUpdate(isAdd, row) {

    setUpdateArray((updateArray) => { // this will provide latest copy of state

      // so here you will always get updated `updateArray`
      const rows = Object.assign([], updateArray);
      const copy = rows.filter(i => i.name !== row.name || i.city !== row.city);
      if (isAdd) {
        copy.push(row);
      }
      console.log(JSON.stringify(copy));
      return copy;
    });

  }

Надеюсь, это поможет вам разобраться в проблеме и способах ее решения.

РАБОЧАЯ ДЕМО:

Edit so-state-update-issue

...