简体   繁体   English

Redux减速机 - 关于状态变化

[英]Redux reducer - on state change

I want to save the current state of a specific reducer into session storage without explicitly calling it on every action. 我想将特定reducer的当前状态保存到会话存储中,而不是在每个操作上显式调用它。

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: []
 }
);

Is there a way to catch the state change event for a specific reducer? 有没有办法捕获特定减速器的状态更改事件?

I know of store.subscribe , but that's for the entire store, i'm talking about listening to a specific reducer change 我知道store.subscribe ,但那是整个商店,我说的是听一个特定的减速器更改

Thanks 谢谢

Unfortunately you can't watch specific parts of your store because your store is actually an only reducer (combineReducers return a single big reducer). 遗憾的是,您无法观看商店的特定部分,因为您的商店实际上只是减速器(combineReducers返回一个大型减速器)。 That said you can manually check if your reducer has changed by doing state part comparison. 也就是说,您可以通过状态部分比较手动检查减速器是否已更改。

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

You can use redux-saga to listen for specific actions and persist the store (and do your other logice) when they are fired. 您可以使用redux-saga来侦听特定操作,并在触发时保留存储(以及执行其他操作)。 This seems like a good fit for your needs. 这似乎非常适合您的需求。

It's not exactly tied to specific store changes, but rather to a set of actions. 它与特定的商店更改并不完全相关,而是与一组操作相关联。 However, I think this model (listening for actions, as opposed to state changes) is better suited to the redux design. 但是,我认为这个模型(倾听动作,而不是状态变化)更适合redux设计。

The nice thing is you don't have to change any code outside of the saga. 好消息是你不必更改传奇之外的任何代码。 I've used this one for autosaving form data and it worked great. 我已经使用这个来自动保存表单数据并且效果很好。

Here's an example of setting up a saga to persist on a few redux-form actions; 这是一个设置一个saga以坚持一些redux-form动作的例子; note that it's not limited to persisting - you can do whatever you want during a saga. 请注意,它不仅限于坚持 - 你可以在传奇期间做任何你想做的事情。

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

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

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

If you want to listen to all action types, or do custom filtering of which actions fire your persistence code, you can pass a pattern, or a matching function to takeLatest: 如果您想要监听所有操作类型,或者自定义过滤哪些操作会激活您的持久性代码,您可以传递模式或匹配函数来获取最新:

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

More on what you can pass to take , takeLatest etc can be found in the docs for take . 更多关于您可以通到什么taketakeLatest等,可以发现在文档的take

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM