6

I'd like to persist some user data to localStorage and need for the store to subscibe to state change but I don't want to fire each time the state changes but rather only when a particular event happens as in my case a user_update event.

Any ways can I have the store to subscribe to a specific event instead of the generic:

store.subscribe(()=>{

//save to local storage here

})

Well thanks heaps for your help :)

Fabrice
  • 465
  • 1
  • 5
  • 17

2 Answers2

7

When you are subscribing to the store, your inner function will fire every time something in store changes. That is the way it meant to be by design. So, you cant respond to event, but you can respond to changes in particular part of the store.

function observeStore(store, select, onChange) {
  let currentState;

  function handleChange() {
    let nextState = select(store.getState());
    if (nextState !== currentState) {
      currentState = nextState;
      onChange(currentState);
    }
  }

  let unsubscribe = store.subscribe(handleChange);
  handleChange();
  return unsubscribe;
}

Then do observeStore(store, select, this.writeToLocalStorageOrWhatever). By the way, for persisting store data in local storage try to use redux-persist.

Check this for more: Redux store API Discussion

Andy Theos
  • 3,216
  • 1
  • 15
  • 24
  • Random question, but is there any advantage to running `currentState = nextState` only when the two states are different? Is there a performance issue with just always swapping out the old state for the new state? – samfrances Nov 17 '18 at 20:46
  • 1
    @samfrances there is no SUCH a performance issue, but conceptually the idea is to change when our state was actually changed. Also this way we will not call the function if our selector returns `undefined`. – Andy Theos Nov 19 '18 at 08:05
0

Instead of subscribe specific events, you could definitely subscribe specific states only in reducers you want.

To do that, you just need to create separate stores.

const store = createStore(combineReducers({
    loginReducer,
    blogReducer
}))
export const store1 = createStore(reducer1)
export const store2 = createStore(reducer2)
export default store;

Then in your component:

import store from './store';
import {store1, store2} from './store';

store.subscribe(() => {
    console.log("subscribe all")
})
store1.subscribe(() => {
    console.log("subscribe only states in reducer 1")
})
store2.subscribe(() => {
    console.log("subscribe only states in reducer 2")
})
bhw1899
  • 87
  • 4