keajs / kea-localstorage

Persist the state of your reducers in localstorage
https://kea.js.org/plugins/localstorage
MIT License
9 stars 3 forks source link

Trigger listener when loading value from localStorage #20

Closed paolodamico closed 3 years ago

paolodamico commented 3 years ago

When a value is loaded from localStorage and the reducer is set, any listener attached to the respective action is not triggered. Example:

export const logic = kea({
  path: () => ["logic1"],
  actions: {
    setToken: (payload) => ({ payload }),
  },
  reducers: {
    token: [null as string | null, { persist: true }, { setToken: (_, { payload }) => payload }],
  },
  listeners: {
    setToken: ({ token }) => {
      // this code won't get called when the reducer is loaded from localStorage
      console.log(token);
    },
  }
});

A current workaround that seems to work for now, though it doesn't seem ideal:

events: ({ actions, values }) => ({
    afterMount: () => {
      actions.loadTokenSuccess(values.token);
    },
}),

Additional context: Sometimes you need to set the value in the context of another class / package (e.g. you want to set the stored authorization token as a default header on your AJAX requests helper class), a perfect use case for a listener.

mariusandra commented 3 years ago

Hmm... Yeah, this is sort of by design. The localstorage plugin sets the default of a reducer. It doesn't call any action, which would have set the value of a reducer. I'm not even sure how to choose which is the "right" action to call in case the reducer has multiple actions that change its value

paolodamico commented 3 years ago

That's true, in that case then the afterMount workaround might be the right approach here to give the dev full control of what actions to use (if applicable). Closing this issue and will make a PR to the docs with a relevant clarification.