Chcę zachować niektóre części mojego drzewa stanu w magazynie localStorage. Jakie jest odpowiednie miejsce, aby to zrobić? Reduktor czy akcja?
źródło
Chcę zachować niektóre części mojego drzewa stanu w magazynie localStorage. Jakie jest odpowiednie miejsce, aby to zrobić? Reduktor czy akcja?
Reduktor nigdy nie jest odpowiednim miejscem do tego, ponieważ reduktory powinny być czyste i nie mieć skutków ubocznych.
Poleciłbym po prostu zrobić to w subskrybencie:
store.subscribe(() => {
// persist your state
})
Przed utworzeniem sklepu przeczytaj te utrwalone części:
const persistedState = // ...
const store = createStore(reducer, persistedState)
Jeśli użyjesz combineReducers()
, zauważysz, że reduktory, które nie otrzymały stanu, „uruchomią się” normalnie, używając domyślnej state
wartości argumentu. To może być bardzo przydatne.
Wskazane jest, aby usunąć subskrybenta, aby nie pisać zbyt szybko do localStorage, w przeciwnym razie będziesz mieć problemy z wydajnością.
Na koniec możesz stworzyć oprogramowanie pośredniczące, które hermetyzuje to jako alternatywę, ale zacznę od subskrybenta, ponieważ jest to prostsze rozwiązanie i dobrze spełnia swoje zadanie.
Aby wypełnić puste miejsca w odpowiedzi Dana Abramowa, możesz użyć
store.subscribe()
tego:Przed utworzeniem sklepu sprawdź
localStorage
i przeanalizuj dowolny kod JSON pod kluczem w następujący sposób:Następnie przekazujesz tę
persistedState
stałą do swojejcreateStore
metody w następujący sposób:źródło
persistedState
zwrócićinitialState
zamiast pustego obiektu? W przeciwnym razie myślę, żecreateStore
zainicjuje się z tym pustym obiektem.Jednym słowem: oprogramowanie pośredniczące.
Sprawdź redux-persist . Lub napisz własne.
[AKTUALIZACJA 18 grudnia 2016 r.] Zmieniono, aby usunąć wzmiankę o dwóch podobnych projektach, które są obecnie nieaktywne lub wycofane.
źródło
Jeśli ktoś ma jakiś problem z powyższymi rozwiązaniami, możesz napisać własne na adres. Pokażę ci, co zrobiłem. Ignoruj
saga middleware
rzeczy, skup się tylko na dwóch rzeczachlocalStorageMiddleware
ireHydrateStore
metodzie.localStorageMiddleware
pociągają za wszystkieredux state
i umieszcza go wlocal storage
irehydrateStore
wyciągnąć wszystkoapplicationState
w pamięci lokalnej, jeśli obecne i umieszcza go wredux store
źródło
localStorage
nawet jeśli nic w sklepie się nie zmieniło? Jak rekompensujesz niepotrzebne zapisyNie mogę odpowiedzieć na @Gardezi, ale opcją opartą na jego kodzie może być:
różnica polega na tym, że po prostu zapisujemy niektóre akcje, możesz użyć funkcji odbicia, aby zapisać tylko ostatnią interakcję twojego stanu
źródło
Trochę się spóźniłem, ale zaimplementowałem stan trwały zgodnie z podanymi tutaj przykładami. Jeśli chcesz aktualizować stan tylko co X sekund, to podejście może Ci pomóc:
Zdefiniuj funkcję opakowania
Wywołaj funkcję opakowania w swoim subskrybencie
W tym przykładzie stan jest aktualizowany co najwyżej co 5 sekund, niezależnie od częstotliwości wyzwalania aktualizacji.
źródło
(state) => { updateLocalStorage(store.getState()) }
wlodash.throttle
ten sposób:store.subscribe(throttle(() => {(state) => { updateLocalStorage(store.getState())} }
i usunąć z niego logikę sprawdzania czasu.Opierając się na doskonałych sugestiach i krótkich fragmentach kodu zawartych w innych odpowiedziach (i artykule Jam Creencia w Medium ), oto kompletne rozwiązanie!
Potrzebujemy pliku zawierającego 2 funkcje, które zapisują / ładują stan do / z lokalnej pamięci:
Te funkcje są importowane przez store.js, gdzie konfigurujemy nasz sklep:
UWAGA: Musisz dodać jedną zależność:
npm install lodash.throttle
Sklep jest importowany do pliku index.js, dzięki czemu można go przekazać do dostawcy opakowującego plik App.js :
Zwróć uwagę, że import bezwzględny wymaga tej zmiany w YourProjectFolder / jsconfig.json - to mówi mu, gdzie szukać plików, jeśli nie może ich na początku znaleźć. W przeciwnym razie zobaczysz skargi dotyczące próby zaimportowania czegoś spoza src .
źródło