aviso Legal
Estado aninhado em React é design incorreto
Leia esta excelente resposta .
Raciocínio por trás desta resposta:
O setState do React é apenas uma conveniência interna, mas você logo percebe que ele tem seus limites. O uso de propriedades personalizadas e o uso inteligente do forceUpdate oferecem muito mais. por exemplo:
class MyClass extends React.Component {
myState = someObject
inputValue = 42
...
O MobX, por exemplo, descarta o estado completamente e usa propriedades observáveis personalizadas.
Use Observables em vez de state nos componentes React.
Há outra maneira mais curta de atualizar qualquer propriedade aninhada.
this.setState(state => {
state.nested.flag = false
state.another.deep.prop = true
return state
})
Em uma linha
this.setState(state => (state.nested.flag = false, state))
Nota: Este aqui é o operador Vírgula ~ MDN ; veja em ação aqui (Sandbox) .
É semelhante a (embora isso não mude a referência de estado)
this.state.nested.flag = false
this.forceUpdate()
Para a diferença sutil neste contexto entre forceUpdate
e setState
veja o exemplo vinculado.
É claro que isso está abusando de alguns princípios básicos, como o state
deve ser somente leitura, mas, como você está descartando imediatamente o estado antigo e o substituindo por um novo estado, está tudo bem.
Atenção
Mesmo que o componente que contém o estado seja atualizado e renderizado corretamente ( exceto essa opção ) , os objetos não serão propagados para os filhos (veja o comentário do Spymaster abaixo) . Use essa técnica apenas se você souber o que está fazendo.
Por exemplo, você pode aprovar uma proposta simples alterada que é atualizada e aprovada com facilidade.
render(
//some complex render with your nested state
<ChildComponent complexNestedProp={this.state.nested} pleaseRerender={Math.random()}/>
)
Agora, mesmo que a referência para complexNestedProp não tenha sido alterada ( shouldComponentUpdate )
this.props.complexNestedProp === nextProps.complexNestedProp
o componente será renderizado novamente sempre que o componente pai for atualizado, que é o caso após a chamada this.setState
ou this.forceUpdate
no pai.
Efeitos da mutação do estado
O uso de estado aninhado e a mutação direta do estado são perigosos porque objetos diferentes podem conter (intencionalmente ou não) referências diferentes (mais antigas) ao estado e podem não necessariamente saber quando atualizar (por exemplo, ao usar PureComponent
ou se shouldComponentUpdate
é implementado para retornar false
) OU são destinado a exibir dados antigos, como no exemplo abaixo.
Imagine uma linha do tempo que supostamente renderiza dados históricos. A mutação dos dados nas mãos resultará em um comportamento inesperado, pois também mudará os itens anteriores.
De qualquer forma, aqui você pode ver que Nested PureChildClass
ele não foi renderizado novamente porque os objetos não foram propagados.