2016-02-10 12 views

Odpowiedz

116

Reduktor nigdy nie jest odpowiednim miejscem do tego, ponieważ reduktory powinny być czyste i nie powodować efektów ubocznych.

Polecam po prostu robi to w abonenta:

store.subscribe(() => { 
    // persist your state 
}) 

Przed utworzeniem sklepu, czytać te przetrwały części:

const persistedState = // ... 
const store = createStore(reducer, persistedState) 

Jeśli używasz combineReducers() zauważysz, że reduktory że raj t otrzyma stan będzie "bootować" normalnie, używając domyślnej wartości argumentu state. To może być bardzo przydatne.

Wskazane jest, aby porzucić subskrybenta, aby nie pisać zbyt szybko do localStorage lub wystąpią problemy z wydajnością.

Wreszcie, można utworzyć oprogramowanie pośrednie, które stanowi alternatywę, ale zacznę od subskrybenta, ponieważ jest to prostsze rozwiązanie i dobrze działa.

+1

co, jeśli chciałbym zapisać się do części państwa? czy to jest możliwe? Poszedłem do przodu z czymś nieco innym: 1. zachowaj stan nadmiarowy poza reduxem. 2. załaduj stan trwały wewnątrz konstruktora reagu (lub z componentWillMount) z działaniem redux. Czy 2 jest całkowicie poprawne zamiast bezpośredniego ładowania utrwalonych danych w sklepie? (które staram się zachować oddzielnie dla SSR). Przy okazji dziękuję za Redux! To niesamowite, uwielbiam to, po zagubieniu się z moim wielkim kodem projektu, teraz wszystko wróci do prostego i przewidywalnego :) –

+0

w sklepie.zasubskrybuj oddzwonienie, masz pełny dostęp do bieżących danych sklepu, dzięki czemu możesz utrwalić każdą część, którą jesteś zainteresowany –

+18

Dan Abramov zrobił także cały film na ten temat: https://egghead.io/lessons/javascript-redux- utrzymywanie stanu na lokalnym przechowywaniu – NateW

34

Jednym słowem: middleware.

Zapoznaj się z redux-persist. Lub napisz własny.

[UPDATE 18 gru 2016] Edytowane w celu usunięcia wzmianki o dwóch podobnych projektach, które są teraz nieaktywne lub przestarzałe.

+2

W Mean Time Redux-storage również wydaje się być opuszczony. – Dani

89

Aby wypełnić formularz odpowiedzi Dan Abramov mógłby użyć store.subscribe() takiego:

store.subscribe(()=>{ 
    localStorage.setItem('reduxState', JSON.stringify(store.getState())) 
}) 

Przed utworzeniem sklepu, sprawdź localStorage i analizować każdą JSON pod klucz jak ten:

const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : {} 

Następnie należy przekazać stałą peristedState do metody createStore w następujący sposób:

const store = createStore(
    reducer, 
    persistedState, 
    /* any middleware... */ 
) 
+1

Proste i skuteczne, bez dodatkowych zależności. – AxeEffect

+1

Tworzenie oprogramowania pośredniego może wyglądać nieco lepiej, ale zgadzam się, że jest ono skuteczne i wystarczające w większości przypadków. –

+0

Czy jest to dobry sposób, aby to zrobić, gdy korzystasz z CombineReducers, a chcesz utrzymać tylko jeden sklep? – brendangibson

0

Jeśli ktoś ma jakikolwiek problem z powyższym, możesz napisać własne. Pozwól, że pokażę ci, co zrobiłem. Ignoruj: saga middleware rzeczy koncentrują się na dwóch metodach: localStorageMiddleware i reHydrateStore. localStorageMiddleware ciągnąć cały redux state i umieszcza go w local storage i rehydrateStore ciągnąć cały applicationState w pamięci lokalnej jeżeli są i umieszcza go w redux store

import {createStore, applyMiddleware} from 'redux' 
import createSagaMiddleware from 'redux-saga'; 
import decoristReducers from '../reducers/decorist_reducer' 

import sagas from '../sagas/sagas'; 

const sagaMiddleware = createSagaMiddleware(); 

/** 
* Add all the state in local storage 
* @param getState 
* @returns {function(*): function(*=)} 
*/ 
const localStorageMiddleware = ({getState}) => { // <--- FOCUS HERE 
    return (next) => (action) => { 
     const result = next(action); 
     localStorage.setItem('applicationState', JSON.stringify(
      getState() 
     )); 
     return result; 
    }; 
}; 


const reHydrateStore =() => { // <-- FOCUS HERE 

    if (localStorage.getItem('applicationState') !== null) { 
     return JSON.parse(localStorage.getItem('applicationState')) // re-hydrate the store 

    } 
} 


const store = createStore(
    decoristReducers, 
    reHydrateStore(),// <-- FOCUS HERE 
    applyMiddleware(
     sagaMiddleware, 
     localStorageMiddleware,// <-- FOCUS HERE 
    ) 
) 

sagaMiddleware.run(sagas); 

export default store; 
Powiązane problemy