2017-10-08 63 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