Search code examples
javascriptreduxredux-toolkit

Understanding how to use preloadedState in redux-toolkit


Im trying to save some things in locale storage and reHydrate the state on refresh.

And it works, but my initalState from my slice file is overwritten.

const reHydrateStore = () => {
    if (localStorage.getItem('culture') !== null) {
        return { login: { culture: JSON.parse(localStorage.getItem('culture')) } };
    }
};

export default reHydrateStore;

Then in configureStore:

preloadedState: reHydrateStore(),

my initalState object looks like this when I dont use reHydrateStore:

const initialState = {
    isLoading: false,
    culture: '',
    error: null,
};

And when I use reHydrateStore:

const initialState = {
    culture: 'en-US',
};

Is there a way to configure the preloadedState to just replace the given prop?

I know I can set up all initalState props in the reHydrateStore method but that seems like awfaul way of doing it. Writing the same code twice feels very unnescesery imo.

Edit:

I moved the logic to the slice to be able to access the initalState. But @Rashomon had a better approach imo and will try with that instead. But here was my first solution:

const reHydrateLoginSlice = () => {
    if (localStorage.getItem("culture")) {
        return {
            login: { ...initialState, culture: JSON.parse(localStorage.getItem("culture")) },
        };
    }
};
export { reHydrateLoginSlice };

Solution

  • Maybe you can define your initialState as this to avoid rewriting the rest of keys:

    const initialState = {
        isLoading: false,
        culture: '', // default value, will be overwrited in following line if defined in the storage
        ...(reHydrateStore() || {}), // if returns undefined, merge an empty object and use previous culture value
        error: null,
    };
    

    If you only need culture to be rehydrated, I would rehydrate only the value instead of an object to make it simpler:

    const initialCultureValue = ''
    
    const initialState = {
        isLoading: false,
        culture: reHydrateCulture() || initialCultureValue,
        error: null,
    };