Как функционал React setState определяет, какие поля были обновлены? - PullRequest
0 голосов
/ 30 апреля 2020

Из моих экспериментов, если у вас есть объект в состоянии реакции (let [state, setState] = useState({})), и вы делаете что-то вроде

setState(s => {
    s.a = 42;
    return s;
})

Он не будет повторно отображать компоненты, которые зависят от s.a. С другой стороны, если вы сделаете

setState(s => {...s, a: 42});

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

Это правильно?

Есть ли способ обновить состояние таким образом, чтобы заставить его только перерисовывать вещи, которые зависят, например, от s.a?

CONTEXT, если это помогает: мне нужно это для моего приложения, потому что производительность становится непрактичной. Мое приложение извлекает информацию JSON из конечной точки API и содержит список «полей», которые описывают поля ввода, которые пользователь может использовать для ввода данных. Когда пользователь закончил, приложение отправляет эти данные в одном json. Таким образом, все входные компоненты управляются через одно функциональное состояние, которое содержит одно свойство на поле (иногда мне нужно иметь возможность программно обновлять некоторые поля). Производительность является непомерной, потому что все поля (довольно много сейчас) обновляются / перерисовываются каждый раз, когда пользователь вводит символ в одном из них. К сожалению, я не могу создать новое состояние для каждого поля, потому что количество полей не известно заранее.

1 Ответ

1 голос
/ 30 апреля 2020

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

setState(s => {
    s.a = 42;
    return s;
})

Невозможно выборочно перерисовать ваш компонент, причина, по которой эта мутация в setState не перерисовывается Дети, которые зависят от sa, потому что ваш компонент вообще не рендерится, когда вы обновляете таким образом, потому что ссылка s не изменяется, поэтому реакция не видит, что есть изменение.

Единственный способ заставить детей не выполнять рендеринг при повторном рендеринге - это использовать React.memo, PureComponent или shouldComponentUpdate. И их нужно применять к дочерним, а не к родительским элементам.

Когда React повторно рендерит дочерний компонент?

...