Почему setState не работает в функциональном компоненте React

const [bullyTypes, setBullyTypes] = React.useState([
  { value: "Exotic", isChecked: false },
  { value: "Pocket", isChecked: false },
  { value: "Classic", isChecked: false },
  { value: "Standard", isChecked: false },
  { value: "Extreme", isChecked: false },
  { value: "XL", isChecked: false },
]);

const handleBullyTypeChange = (event) => {
  let bullyTypesCopy = bullyTypes;
  bullyTypesCopy.forEach((bullyTypeCopy) => {
    if (bullyTypeCopy.value === event.target.value) {
      bullyTypeCopy.isChecked = event.target.checked;
    }
  });
  setBullyTypes(bullyTypesCopy); // not working

  setBullyTypes([
    { value: "Exotic", isChecked: true },
    { value: "Pocket", isChecked: false },
    { value: "Classic", isChecked: false },
    { value: "Standard", isChecked: false },
    { value: "Extreme", isChecked: false },
    { value: "XL", isChecked: false },
  ]); // this is working even though bullyTypesCopy variable has the same value with this array of objects.
};

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

Помогите мне, пожалуйста. Спасибо


person jay philip camillo    schedule 19.06.2020    source источник
comment
Можете ли вы показать нам, как вы используете setState, потому что его нет в коде.   -  person Jovylle Bermudez    schedule 19.06.2020
comment
Не мутируйте объекты, они сравниваются по ссылке. См. reactjs.org/docs/state-and-lifecycle.html. #использование-состояния-правильно   -  person Juan Mendes    schedule 19.06.2020
comment
Привет. Я имею в виду, что setState в моем коде — это setBullyTypes. :)   -  person jay philip camillo    schedule 19.06.2020


Ответы (1)


В обработчике событий bullyTypesCopy копируется по ссылке, а forEach не делает того, что вы ожидаете, он просто перебирает элементы массива. Я думаю, что вам нужно использовать map, чтобы фактически получить новый контент в зависимости от вашего состояния. Таким образом, setBullyTypes должно работать.

Пожалуйста, попробуйте следующий пример

const [bullyTypes, setBullyTypes] = React.useState([
  { value: "Exotic", isChecked: false },
  { value: "Pocket", isChecked: false },
  { value: "Classic", isChecked: false },
  { value: "Standard", isChecked: false },
  { value: "Extreme", isChecked: false },
  { value: "XL", isChecked: false },
]);

const handleBullyTypeChange = (event) => {
  let bullyTypesCopy = bullyTypes.map((bullyTypeCopy) => {
    if (bullyTypeCopy.value === event.target.value) {
      return { ...bullyTypeCopy, isChecked: !event.target.checked };
    }

    return { ...bullyTypeCopy };
  });

  setBullyTypes(bullyTypesCopy); // not working // this should work now

  setBullyTypes([
    { value: "Exotic", isChecked: true },
    { value: "Pocket", isChecked: false },
    { value: "Classic", isChecked: false },
    { value: "Standard", isChecked: false },
    { value: "Extreme", isChecked: false },
    { value: "XL", isChecked: false },
  ]); // this is working even though bullyTypesCopy variable has the same value with this array of objects.
};
person Mario    schedule 19.06.2020
comment
Правильный. OP думает, что let bullyTypesCopy = bullyTypes создает новый объект, вместо этого присваивание создает только ссылку на объект bullyTypes, что означает попытку напрямую манипулировать значением состояния. Однако более простой способ копирования объекта может быть реализован с помощью Object.assign. В этом конкретном случае let bullyTypesCopy = Object.assign({ }, bullyTypes) должно помочь. - person cmlndz; 19.06.2020