2016-02-10 30 views

回答

116

減速機永遠不是合適的地方,因爲減速機應該是純淨的,沒有副作用。

我會建議只是在做它在用戶:

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

之前創建存儲,讀取那些堅持部分:

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

如果使用combineReducers()你會發現,這減速器避風港收到的狀態將使用默認值state的參數值「正常啓動」。這可以非常方便。

建議您消除訂閱者的注意力,以免寫入localStorage的速度過快,否則會出現性能問題。

最後,您可以創建一箇中間件,將其作爲替代方案進行封裝,但我會先從訂閱者開始,因爲它是一個更簡單的解決方案,並且可以很好地完成這項工作。

+1

如果我想訂閱只是國家的一部分?那可能嗎?我繼續做一些有點不同的事情:1.在redux之外保存持久狀態。 2.使用redux動作加載反應構造函數(或componentWillMount)中的持久狀態。 2是完全正確的,而不是直接在商店中加載持久數據? (我試圖單獨保存SSR)。順便謝謝Redux!這是真棒,我喜歡它,在我的大項目代碼迷路後,現在回到簡單和可預測的:) –

+0

在店內。訂閱回撥,您可以完全訪問當前的商店數據,因此您可以保留您感興趣的任何部分 –

+18

Dan Abramov也製作了一個完整的視頻: https://egghead.io/lessons/javascript-redux-持久化狀態到本地存儲 – NateW

34

總之:中間件。

結賬redux-persist。或者寫你自己的。

[更新日期2016年12月18日]編輯刪除提及兩個現在不活動或不贊成使用的類似項目。

+2

與此同時Redux的存儲似乎也被拋棄。 – Dani

89

要在丹·阿布拉莫夫的回答填補空白,你可以使用store.subscribe()這樣的:

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

創建商店之前,檢查localStorage和你的鑰匙像這樣在解析任何JSON:

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

然後您將此peristedState常數傳遞給您的createStore這樣的方法:

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

簡單而有效,無需額外依賴。 – AxeEffect

+1

創建一箇中間件可能看起來好一點,但我同意它是有效的,並且足以在大多數情況下 –

+0

使用combineReducers時是否有一個很好的方法來執行此操作,並且您只需要堅持一個存儲? – brendangibson

0

如果有人對上述有任何問題,你可以寫你自己的。讓我告訴你我做了什麼。忽略saga middleware的事情只關注兩件事localStorageMiddlewarereHydrateStore方法。該localStorageMiddleware把所有的redux state,並把它放在local storagerehydrateStore把所有的applicationState在本地存儲中如果存在的話,並把它放在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; 
相關問題