При записи в стейт объект меняется — откуда такая дичь?

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

Когда вы изменяете объект, находящийся в стейте React-компонента, это изменяет ссылку на этот объект, а не сам объект. Это происходит потому, что JavaScript передает объекты по ссылке, а не по значению. Таким образом, React оптимизирует производительность, устанавливая новую ссылку на объект в стейте только тогда, когда объект действительно изменился.

Такая стратегия оптимизации позволяет React сравнивать новую ссылку на объект с предыдущей с помощью "поверхностного сравнения" (shallow comparison). Если React обнаруживает, что ссылка на объект изменилась, то он перерендерит компонент и обновит пользовательский интерфейс. Если же ссылка на объект осталась неизменной, то React не будет выполнять дополнительных действий, чтобы обновить пользовательский интерфейс, так как он считает, что объект остался неизменным.

В контексте изменения объекта в стейте React-компонента, "откуда такая дичь" является причиной проблемы с производительностью. Если вы напрямую изменяете объект в стейте React-компонента, React не сможет обнаружить изменения и не будет перерисовывать компонент, что приведет к некорректной работе приложения. Поэтому важно создавать новые объекты и массивы при изменении стейта и избегать изменения объектов напрямую.

Для создания новых объектов или массивов в React можно использовать различные методы, такие как spread-оператор или методы копирования объектов, такие как Object.assign(). Используя эти методы, вы можете создать новый объект, который содержит все свойства и значения существующего объекта и имеет возможность добавления или изменения свойств.

Например, если у вас есть объект в стейте компонента:

this.setState({
  myObject: {
    ...this.state.myObject, // распыляем существующие свойства myObject
    новоеСвойство: 'новое значение' // добавляем новое свойство
  }
});

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