简体   繁体   中英

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.

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

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). 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. 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.

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; 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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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