2017-10-08 68 views
1

我想將特定reducer的當前狀態保存到會話存儲中,而不必在每個操作中明確調用它。Redux reducer - on state change

const { handleActions } = require("redux-actions"); 

// How do i make this logic run on any state change without adding it to every action? 
const onStateChange = (state) => sessionStorage.save(keys.myReducer, state); 

const myReducer = handleActions 
({ 
    [Actions.action1]: (state, action) => (
     update(state, { 
      prop1: {$set: action.payload}, 
     }) 
    ), 
    [Actions.action2]: (state, action) => (
     update(state, { 
      prop2: {$set: action.payload}, 
     }) 
    ) 
}, 
//****************INITIAL STATE*********************** 
{ 
    prop1: [], 
    prop2: [] 
} 
); 

有沒有辦法趕上特定減速的狀態變化的事件嗎?

我知道store.subscribe,但是這對整個商店,我說的是聽一個特定的減速變化

感謝

+0

您是否嘗試過像[redux-localstorage](https://github.com/elgerlambert/redux-localstorage)或[redux-persist](https://github.com/rt2zz/redux-persist)這樣的庫?或者你是否正在處理這些庫無法解決的利基用例? – excalliburbd

+0

@excalliburbd - 堅持狀態不是唯一的邏輯我想運行狀態改變,所以不幸的是這並不能解決問題 – Daniel

回答

3

可惜你不能看你的商店的特定部分,因爲你的店實際上是一個唯一的減速器(組合減速器返回一個大的減速器)。這就是說你可以通過狀態部分比較來手動檢查你的reducer是否已經改變。

let previousMyReducer = store.getState().myReducer; 
store.subscribe(() => { 
    const { myReducer } = store.getState(); 
    if (previousMyReducer !== myReducer) { 
    // store myReducer to sessionStorage here 
    previousMyReducer = myReducer; 
    } 
}) 
+0

你確定這樣的參考比較是有效的嗎?如果有任何價值變化,減排者的參考變化(只有變化)嗎? – Daniel

+1

是的,它是減速器不變性的主要優點,當減速器不攔截動作時,返回狀態的相同參考返回 – Freez

0

您可以使用redux-saga監聽的具體行動和持久化存儲(做你的其他logice),當他們被解僱。這看起來很適合您的需求。

它並不完全綁定到特定的商店更改,而是一組操作。然而,我認爲這個模型(傾聽行動,而不是狀態變化)更適合於redux設計。

好的是你不必改變任何代碼以外的任何代碼。我用這個自動保存表單數據,它工作得很好。

下面是一個例子,設置一個傳奇以堅持幾個簡約形式的動作;請注意,它並不侷限於堅持 - 在傳奇中你可以做任何你想做的事。

function* autosaveSaga(apiClient) { 
    yield throttle(500, 
    reduxFormActionTypes.CHANGE, 
    saveFormValues, 
    apiClient); 

    yield takeLatest(
    reduxFormActionTypes.ARRAY_PUSH, 
    saveFormValues, 
    apiClient); 

    yield takeLatest(
    reduxFormActionTypes.ARRAY_POP, 
    saveFormValues, 
    apiClient); 
} 

如果你想要聽的所有動作類型,或做自定義篩選這些行動激發你的持久代碼,你可以通過一個模式,或者一個匹配功能takeLatest:

yield takeLatest(
    '*', 
    saveFormValues, 
    apiClient); 

更多你可以通過什麼方式到taketakeLatest等可以找到in the docs for take

+0

謝謝,但這正是我想要避免..(寫相同的行對每一個動作) – Daniel

+0

我的例子不是最優的。更新後請注意,您可以使用模式或匹配所有操作。 – stone