Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rehydrate causes unrelated keys not visible in the store #269

Open
MikeDabrowski opened this issue Sep 9, 2024 · 2 comments
Open

Rehydrate causes unrelated keys not visible in the store #269

MikeDabrowski opened this issue Sep 9, 2024 · 2 comments
Labels
feature stores Functionality related to feature stores / modules

Comments

@MikeDabrowski
Copy link

MikeDabrowski commented Sep 9, 2024

my sync config:

const localStorageSyncConfig: LocalStorageConfig = {
  keys: [{ appState: ['mode'] }],
  rehydrate: true,
  storageKeySerializer: (key: string) => `ngrx-sync-${key}`,
};

my store (relevant piece)

export const initialState: AppState = {
  mode: Mode.Light,
  countries: [],
  version: undefined,
  build: undefined,
  edition: undefined,
  test: 'undefined',
  localStorage: {
    restorePdfTooltipDismissed: true,
  },
};

And after the app starts. The store does not have test and localStorage properties at all. Even though they were not mentioned in the config. The properties that are in the store are set later (after rehydration) via various other actions. The missing ones I added while debugging, they are only in the initialState, not mentioned in other places.

I'd expect them to be ignored because they are not mentioned in the config. I am now afraid to use this tool because it can remove other properties too.

Actually it is a duplicate of:
#268

@MikeDabrowski
Copy link
Author

MikeDabrowski commented Sep 9, 2024

I spent few hours to investigate

in ngrx the feature store reducer is defined more-less like so:

reducer(state = initialState, action) {
// here it looks for reducers that actions provide and if not found it returns the state
} 

Now if we set the store state in meta reducer before this feature store gets set up, then the initialState will never be used. (technically 'never' is probably not correct - maybe there is some special case that will use it, like action that will just set the initialState again)

So the rehydration sets the state recovered from LocalStorage as the initial state, then the state defined in initialState of feature modules will never be applied. And only state pieces that are set as a result of subsequent actions will populate rest of the store.

Why is this bad ?

If you have any key defined in initialState of any store it will go missing until you fire an action that will set it explicitly. This is true for any substore that matches top level of any keys defined in the config. I think it is very easy to find a real life example when this is bad.

Is there any chance to have it fixed ?

Slim

One could try to merge rehydrated state with initial state of each store. But I can't foresee the unexpected side effects at this point.

const featureStoreReducer = createReducer(
  initialState,
  on({ type: '@ngrx/store/update-reducers' } as any, (state) => {
    const item = JSON.parse(localStorage.getItem(`ngrx-sync-appState`) || '{}');
    return { ...state, ...initialState, ...item };
  }),
...

@BBlackwo BBlackwo added the feature stores Functionality related to feature stores / modules label Sep 9, 2024
@BBlackwo
Copy link
Collaborator

BBlackwo commented Sep 9, 2024

Hi @MikeDabrowski thanks for the thorough issue and investigation.

There are several issues with feature stores, and various workarounds mentioned in those issues as well. There are a few PRs with suggested fixes too.

This project is mostly in maintenance mode at this point, so I'm hesitant to do any large changes. There isn't enough test coverage to be confident in changes, and it's hard to get feedback from enough users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature stores Functionality related to feature stores / modules
Projects
None yet
Development

No branches or pull requests

2 participants