отказ
Вложенное состояние в React - неправильный дизайн
Прочитайте этот отличный ответ .
Причины этого ответа:
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))
примечание: здесь это оператор запятой ~ MDN , посмотрите его в действии (песочница) .
Это похоже на (хотя это не меняет ссылку на состояние)
this.state.nested.flag = false
this.forceUpdate()
Для тонкой разницы в этом контексте между forceUpdate
и setState
посмотрите связанный пример.
Конечно, это злоупотребление некоторыми основными принципами, так как они state
должны быть доступны только для чтения, но, поскольку вы немедленно отбрасываете старое состояние и заменяете его новым, это вполне нормально.
Предупреждение
Даже если компонент, содержащий состояние, будет обновляться и перерисовываться должным образом ( кроме этой ошибки ) , реквизиты не смогут распространяться на детей (см. Комментарий 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
он не рендерится из-за того, что реквизит не распространяется.