Istnieje great video na temat korzyści i implementacji niezmiennych danych, od przemówienia Lee podczas konferencji React Conf 2015. Jeśli chodzi o dane niezmienne i reagowanie, uważam to za istotne przeglądanie.
Poza tym, oto kilka własnych przemyśleń w tej sprawie.
Kod terser
Im bardziej skomplikowana twój stan, tym trudniej jest zarządzać z literałów i operatora rozprzestrzeniać. Wyobraźmy sobie, że zamiast być płaski, trzeba było kilka poziomów stanu zagnieżdżonego:
const initialState = {
core: {
tracker: {
activeTrackId: '',
state: 'stopped'
}
}
};
Mimo to nadal można użyć operatora spread, to zaczyna być nużące.
return {
...state,
core: {
...state.core,
tracker: {
...state.core.tracker,
activeTrackId: action.state !== 'stopped' ? action.track._id : '',
state: action.state
}
}
};
Teraz spójrz na odpowiednik w pliku Immutable.js.
import { Map } from 'immutable';
const initialState = Map({
core: Map({
tracker: Map({
activeTrackId: '',
state: 'stopped'
})
})
});
Następnie możemy użyć trwałego API, aby dokonać głębokich zmian w strukturze.
return state
.setIn(
['core', 'tracker', 'activeTrackId'],
action.state !== 'stopped' ? action.track._id : ''
)
.setIn(
['core', 'tracker', 'state'],
action.state
);
Warto nadmienić, że w zależności od kształtu państwa może być bardziej sensowne dzielenie i zagnieżdżanie reduktorów.
Sharing Structural
Po dokonaniu modyfikacji obiektu z ImmutableJS że korzysta z faktu, że jest on realizowany z hash odwzorowane wektor stara się dzielić najbardziej struktury między starego obiektu i zmodyfikowanej wersji.
Podczas korzystania z operatora rozprzestrzeniania do tworzenia nowych literałów, jesteś zmuszony skopiować więcej danych, niż potrzebujesz do wytworzenia nowego obiektu.
Bezpieczeństwo
można wyeliminować ogromną klasę błędów poprzez zagwarantowanie, że obiekt nie może być zmutowany.
W stanie zmiennym możliwe jest przekazanie odwołania do obiektu do innego kodu, który może go zmutować. Mutowanie obiektu nie jest "błędem", więc nie zostaniesz poinformowany, że to się zmieniło, a także nie będzie śladu stosu, co oznacza, że bardzo trudno jest ustalić, skąd pochodzi mutacja.
Gdziekolwiek są twoje niezmienne obiekty, będą bezpieczne.
Wydajność
Można użyć niezmiennej struktury danych do bardziej zaawansowanych decyzje o tym, czy należy aktualizować składniki, czy też nie.
shouldComponentUpdate(nextProps) {
const oldProps = Immutable.fromJS(this.props);
const newProps = Immutable.fromJS(nextProps);
return !Immutable.is(oldProps, newProps);
}
Chociaż te rodzaje głębokich porównań może wydawać się drogie, one uniemożliwić konieczności diff lub dotknij DOM gdy przedmioty nie uległy zmianie.
Będzie to jeszcze bardziej skuteczne, jeśli twoje rekwizytki będą niezmiennymi obiektami, ponieważ fromJS
nie będzie musiał odtwarzać zagnieżdżonych poziomów.
Świetna odpowiedź, Dan! To naprawdę pomaga mi lepiej zrozumieć Niezmienny. Nie byłem pewien, czy używać "Map", czy "Record", ani jak korzystać z tych rzeczy. Uważam, że dokumentacja jest trochę myląca. Zastanawiam się, dlaczego zdecydowali się użyć formatu '.setIn (['core', 'tracker', 'activeTrackId'], value)' w przeciwieństwie do '.setIn ('core.tracker.activeTrackId', value)'. – ffxsam
Jeśli wolisz ten styl zapisu, istnieją biblioteki takie jak [dot-prop-immutable] (https://github.com/debitoor/dot-prop-immutable). –
PS: Jeszcze krócej, możesz po prostu użyć 'Immutable.fromJS' i przekazać cokolwiek, a on ustawi odpowiednią ilość map i list dla ciebie. – ffxsam