Реагируйте на странную неявную мутацию состояния

#javascript #reactjs

Вопрос:

У меня есть компонент TaskManager, в котором у меня есть состояние

 const [sections, setSections] = useState({
sectionArr: [/*some stuff*/],
taskArr: [/*some stuff*/],
})
 

и куча conlole.log s

   console.log("Sections is", sections);
  console.log("Type: ", typeof sections);
 

Также у меня есть кнопка AddSectionButton, которая в основном представляет собой кнопку, добавляющую новые разделы.
Это функция обратного вызова onClick

   const handleClick = () => {
    const newObject = {
      name: "added section",
      id:
        // random id
        Math.floor(Math.random() * (Number.MAX_VALUE - 0))   0,
      position: 0,
    };
    const sectionsCopy = sections;
    const updatedState = sectionsCopy.sectionArr.push(newObject);

    setSections(updatedState);
  };
 

Когда я сначала запускаю свое приложение, все в порядке, my console.log вывод правильный

 Sections is {sectionArr: Array(3), taskArr: Array(3)}
Type:  object
(3) [{…}, {…}, {…}]
ƒ map() { [native code] }
 

Но потом, когда я нажимаю кнопку добавления, вывод становится действительно странным

 Sections is 4
Type:  number
 

Я никоим образом не изменил все свое состояние с 4.
Есть какие-нибудь идеи о том, почему меняется мое состояние?

Комментарии:

1. Если вы утешите. войдите в журнал updatedState перед запуском setSections(updatedState); , что он показывает?

Ответ №1:

метод rray#push работает на месте, вам не нужно назначать его новой переменной. Он не вернет новый массив, но изменит исходный и вернет его длину. Вот почему в результате вы получаете номер.

Я бы сделал что-то подобное вместо использования push

 updateState = { sectionArr: [...sectionsCopy.sectionArr, newObject], taskArr: [...sectionsCopy.taskArr] }
 

Или даже, возможно, использовать переменную sectionsCopy для передачи в наборы, потому что использование push изменит эту переменную и вернет число.