Відмова від відповідальності
Вкладений стан в React - неправильний дизайн
Прочитайте цю чудову відповідь .
Обґрунтування цієї відповіді:
Реакція setState - це просто вбудована зручність, але ви незабаром зрозумієте, що вона має свої межі. Використання спеціальних властивостей та інтелектуальне використання forceUpdate дає значно більше. наприклад:
class MyClass extends React.Component {
myState = someObject
inputValue = 42
...
Наприклад, MobX повністю викочує стан та використовує власні спостережувані властивості.
Використовуйте Observables замість стану в компонентах React.
Існує ще один коротший спосіб оновити будь-яке вкладене властивість.
this.setState(state => {
state.nested.flag = false
state.another.deep.prop = true
return state
})
По одному рядку
this.setState(state => (state.nested.flag = false, state))
Примітка. Це ось оператор Comma ~ MDN , дивіться це в дії тут (пісочниця) .
Це схоже на (хоча це не змінює посилання на стан)
this.state.nested.flag = false
this.forceUpdate()
Для тонкої різниці в цьому контексті між forceUpdate
і setState
див. Зв'язаний приклад.
Звичайно, це зловживання деякими основними принципами, як це state
повинно бути лише для читання, але оскільки ви негайно викидаєте старий стан і заміняєте його новим, це абсолютно нормально.
Увага
Навіть незважаючи на те, що компонент, що містить стан, буде належним чином оновлюватися та надаватись ( окрім цього gotcha ) , реквізит не зможе поширюватись на дітей (див. Коментар Spymaster нижче) . Використовуйте цю техніку лише тоді, коли ви знаєте, що робите.
Наприклад, ви можете передати змінену плоску опору, яка оновлюється та передається легко.
render(
//some complex render with your nested state
<ChildComponent complexNestedProp={this.state.nested} pleaseRerender={Math.random()}/>
)
Тепер навіть незважаючи на те, що посилання на complexNestedProp не змінилося ( shouldComponentUpdate )
this.props.complexNestedProp === nextProps.complexNestedProp
компонент буде видаватись щоразу, коли батьківський компонент оновлюється, що є випадком після виклику this.setState
або this.forceUpdate
в батьківському.
Наслідки мутації стану
Використання вкладеного стану і мутує стан безпосередньо небезпечно , тому що різні об'єкти можуть тримати (навмисно чи ні) різні (старі) посилання на стан і не обов'язково знати , коли оновлення (при використанні, наприклад , PureComponent
або , якщо shouldComponentUpdate
здійснюється для повернення false
) або є призначені для відображення старих даних, як у наведеному нижче прикладі.
Уявіть, що часова шкала, яка повинна відображати історичні дані, мутація даних під рукою призведе до несподіваної поведінки, оскільки це також змінить попередні елементи.
У будь-якому випадку тут можна побачити, що Nested PureChildClass
він не відтворювався через реквізит, який не вдалося поширити.