Zrzeczenie się
Stan zagnieżdżony w React jest niepoprawny
Przeczytaj tę doskonałą odpowiedź .
Uzasadnienie tej odpowiedzi:
React's setState to tylko wbudowana wygoda, ale wkrótce zdajesz sobie sprawę, że ma swoje ograniczenia. Korzystanie z niestandardowych właściwości i inteligentne użycie forceUpdate daje znacznie więcej. na przykład:
class MyClass extends React.Component {
myState = someObject
inputValue = 42
...
Na przykład MobX całkowicie wykopuje stan i używa niestandardowych obserwowalnych właściwości.
Użyj składników Obserwowalne zamiast stanu w komponentach React.
Tam jest inny krótszy sposób aktualizacji dowolnej zagnieżdżonej właściwości.
this.setState(state => {
state.nested.flag = false
state.another.deep.prop = true
return state
})
W jednej linii
this.setState(state => (state.nested.flag = false, state))
Uwaga: tutaj jest operator przecinkowy ~ MDN , zobacz tutaj w akcji (piaskownica) .
To jest podobne do (chociaż to nie zmienia odniesienia stanu)
this.state.nested.flag = false
this.forceUpdate()
Dla subtelnej różnicy w tym kontekście między forceUpdate
isetState
patrz połączony przykład.
Oczywiście narusza to niektóre podstawowe zasady, takie jak state
powinno być tylko do odczytu, ale ponieważ natychmiast odrzucasz stary stan i zastępujesz go nowym, jest to całkowicie w porządku.
Ostrzeżenie
Nawet jeśli składnik zawierający stan będzie aktualizować i rerender prawidłowo ( z wyjątkiem tego Gotcha ) , rekwizyty będą nie propagować dzieci (patrz komentarz Spymaster za poniżej) . Użyj tej techniki tylko wtedy, gdy wiesz, co robisz.
Na przykład możesz przekazać zmieniony płaski rekwizyt, który można łatwo zaktualizować i przekazać.
render(
//some complex render with your nested state
<ChildComponent complexNestedProp={this.state.nested} pleaseRerender={Math.random()}/>
)
Teraz, mimo że odwołanie do complexNestedProp nie uległo zmianie ( shouldComponentUpdate )
this.props.complexNestedProp === nextProps.complexNestedProp
komponent zwróci się ponownie po każdej aktualizacji komponentu nadrzędnego, co ma miejsce po wywołaniu this.setState
lub this.forceUpdate
w elemencie nadrzędnym.
Skutki mutowania państwa
Korzystanie stan zagnieżdżony i mutowania stan bezpośrednio jest niebezpieczne, ponieważ różne obiekty mogą posiadać (celowo lub nie) różne (starsze) odniesienia do państwa i niekoniecznie musi wiedzieć, kiedy do aktualizacji (przy użyciu na przykład PureComponent
czy shouldComponentUpdate
jest realizowany do zwrotu false
) OR są przeznaczony do wyświetlania starych danych, jak w poniższym przykładzie.
Wyobraź sobie oś czasu, która ma renderować dane historyczne, mutacja danych pod ręką spowoduje nieoczekiwane zachowanie, ponieważ zmieni także poprzednie elementy.
W każdym razie tutaj możesz zobaczyć, Nested PureChildClass
że nie został ponownie przesłany z powodu braku propagacji rekwizytów.