Одна из самых важных вещей, которые нужно помнить о правильном использовании состояния в React, — это всегда избегать прямого изменения состояния. Например, вы бы не стали делать следующее:

this.state.comment = 'Hey!'; это действительно неправильно!

this.setState({comment: 'Hey!'}); вот как ты это делаешь!

this.state можно назначить только в конструкторе следующим образом:

Поскольку обновления состояния могут быть асинхронными,

React может объединять несколько вызовов setState() в одно обновление для повышения производительности. Следовательно, их значения ненадежны для расчета следующего состояния. Из-за этого ограничения мы можем использовать другую форму setState(), которая принимает функцию, а не объект, как показано ниже. Передаваемые аргументы функции: 1.) предыдущее состояние и 2.) свойства во время применения обновления:

Обновления состояния объединены

Когда вызывается setState(), React объединяет предоставленный объект с текущим состоянием. В приведенном ниже коде показано, как обновляется состояние, когда оно содержит более одной независимой переменной. В этом примере у нас есть состояние, установленное для двух независимых переменных пустого массива, posts и comments:

То, что происходит выше, представляет собой неглубокое слияние, когда this.setState({comments}) не изменяет this.state.posts, а вместо этого полностью заменяет this.state.comments. this.setState() обновляет каждую независимую переменную состояния по отдельности, чтобы она не изменяла другую.

Односторонний поток данных в React

Родительские и дочерние компоненты не знают, является ли определенный компонент с сохранением состояния или без него, и, поскольку он является локальным для компонента, он доступен только тому, кто владеет им и устанавливает его. Способ передать состояние дочерним элементам компонента — передать его в качестве реквизита. Этот однонаправленный поток данных является ключевым атрибутом React, где родительский компонент владеет состоянием и изменяет его, в то время как дочерние элементы этого компонента, расположенные ниже родителя в дереве компонентов, могут получать состояние в качестве свойств. Дети не могут добраться до родительского компонента, чтобы изменить состояние. Вместо этого они получают состояние от родительского компонента в виде props или свойств. Props в React никогда не изменяются компонентом и должны вести себя как чистые функции по отношению к своим props. Это означает, что все функции, связанные с реквизитами, не должны пытаться изменить свои входные данные и всегда возвращать один и тот же результат для одних и тех же входных данных. В этом суть «чистой» функции. Кроме того, состояние родительского компонента влияет только на те компоненты, которые находятся ниже него в иерархии дерева состояний.

Компоненты, контролируемые React

В React изменяемое состояние обычно сохраняется в свойстве состояния компонентов и обновляется только с помощью setState(). Контролируемая форма — это форма, которая получает свои входные значения из состояния. В приведенном ниже коде мы явно устанавливаем значение компонента и обновляем это значение в ответ на изменения, которые вносит пользователь. Я устанавливаю value={this.state.name}в строке 39 и value={this.state.checked}в строке 44. Обработчик события onChange ссылается на функцию handleChange, которая обновляет состояние через this.setState(), устанавливая имя в значение, которое пользователь ввел на входе. Обратите внимание, что обработчик события onChange onChange={this.handleChange} написан с тем же синтаксисом, что и свойство React. Сначала я устанавливаю свойство name в состоянии на пустую строку. Когда пользователь вводит что-то во входные данные, это значение захватывается и устанавливается как новое состояние с помощью функции стрелки handleChange и this.setState(), что запускает повторный рендеринг. Ссылка на binding и this из моей предыдущей записи в блоге. В моем контролируемом компоненте ниже, что касается отправленной формы, весь объект состояния представляет собой просто данные контролируемой формы. Весь этот объект отправляется через запрос POST на серверную часть. Все контролируемые входные данные, которые содержат значение состояния в тегах <form>, отправляются функцией handleSubmit на серверную часть через запрос POST, как показано в приведенном ниже коде.