Дочерний объект не воспроизводится, если реквизит установлен с помощью useState () - PullRequest
1 голос
/ 06 февраля 2020

У меня есть ситуация, когда у меня есть родительский (App) и дочерний (MUIDatatable) компонент. Дочерний объект - это набор данных, который принимает columns prop, описывающий структуру столбцов, а также определяет пользовательскую функцию рендеринга для одного из них. В этой пользовательской функции рендеринга я создаю экземпляр кнопки, для которого состояние disabled должно зависеть от состояния родителя, от значения buttonsDisabled, которое устанавливается через хук useState(). До этого момента все работало нормально, но когда я также меняю опору columns, используя useState(), повторное рендеринг больше не срабатывает при изменении значения buttonsDisabled. Код выглядит следующим образом:

  const App = () => {
  const [buttonsDisabled, setButtonsDisabled] = useState(false);

  const tableData = {
    columns: [
      { name: "name", label: "Name", options: {} },
      {
        name: "action",
        label: "Action",
        options: {
          customBodyRender: v => (
            <button disabled={buttonsDisabled}>button</button>
          )
        }
      }
    ],
    data: [["A", null], ["B", null], ["C", null], ["D", null]]
  };

  const btnOnClick = () => {
    setButtonsDisabled(true);
  };

  /***** discussed part of code *****/
  const [columns] = useState(tableData.columns); // if we use this, buttons are not disabled
  //const columns = tableData.columns; // if we use this, buttons are properly disabled
  /**********************************/

  return (
    <div>
      <button onClick={btnOnClick}>DISABLE BUTTONS</button>
      <MUIDataTable title="title" data={tableData.data} columns={columns} />
    </div>
  );
};

Он также доступен в codeandbox: https://codesandbox.io/s/muidatatables-custom-toolbar-cy4vg

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

Что я не могу понять, так это почему useState используется для модификации * Значение 1021 * предотвратит срабатывание указанной функции customBodyRender при изменении значения buttonsDisabled, тогда как установка с помощью простого назначения работает просто отлично. В обоих случаях это все-таки ссылка на один и тот же массив. Я полагаю, что это некое простое понятие, которое мне не хватает, но я был бы признателен за помощь в указании, что это такое.

1 Ответ

1 голос
/ 06 февраля 2020

Когда вы создаете исходное состояние columns, ваша функция customBodyRender получает доступ к переменной buttonsDisabled внешней функции (см .: closure ), которая по умолчанию равна false. После инициализации ваша переменная columns сохраняется в вашем состоянии, а переменная buttonsDisabled внутри customBodyRender будет продолжать ссылаться на исходное значение из внешней функции.

Возможно ли вам вместо этого передать buttonsDisabled в компонент таблицы MUIDataTable и, возможно, передать его в качестве аргумента функции customBodyRender?

customBodyRender: (v, disabled) => (
  <button disabled={disabled}>button</button>
)
...