reactjsreduxlocal-storageredux-persist

Is there redux-persist API to sync localStorage change to redux-persist?


I have a Redux app that uses redux-persist to store auth jwt token. The app will get the token from the redux store to be put to HTTP Authorization header.

The problem here is that whenever I login to other user in another tab, the redux store is not updated with the newly logged in user token. (although the localStorage is updated with the newly logged in user token)

So I wonder if there is a best practice to do this by setting some options to redux-persist?

Or do I need to add a localStorage listener to update the redux store whenever there is a localStorage change?

I hope my explanation is understandable.

Thank you


Solution

  • No, there are no build-in api for this!

    You can use storage event :

    import { legacy_createStore as createStore,Store, applyMiddleware} from "redux";
    import reducer from "./reducer";
    import { persistReducer } from "redux-persist";
    import storage from "redux-persist/lib/storage";
    import persistStore from "redux-persist/es/persistStore";
    
    
    const persistConfig = {
        key:"root",
        storage:storage,
        blacklist:["loading"]
    }
     
    const persistedReducer = persistReducer( persistConfig , reducer );
    const store = createStore(
        persistedReducer, 
        {counter:0}, // initial state
    );
     
    const persistor = persistStore(store);
    export {store , persistor};
    
    
    /* this event update state when storage changed! */
    window.addEventListener('storage',(e)=>{
        const persistData = JSON.parse(localStorage.getItem('persist:root'));
        const newCounterValue = parseInt(persistData.counter);
        console.log(newCounterValue);
        store.dispatch({type:'SET_VALUE',payload:newCounterValue})
    })
    

    other option is redux-state-sync package.redux-state-sync is a middleware for redux

    npm i redux-state-sync
    

    in this example when counter changed in localstorage , all tab will recieved new state value!

    import { legacy_createStore as createStore,Store, applyMiddleware} from "redux";
    import reducer from "./reducer";
    import { persistReducer } from "redux-persist";
    import storage from "redux-persist/lib/storage";
    import persistStore from "redux-persist/es/persistStore";
    
    import {
        createStateSyncMiddleware,
        initMessageListener,
    } from "redux-state-sync";
     
    const persistConfig = {
        key:"root",
        storage:storage,
        blacklist:["loading"]
    }
     
    const persistedReducer = persistReducer( persistConfig , reducer );
    const store = createStore(
        persistedReducer, 
        {counter:0}, // initial state
        applyMiddleware(createStateSyncMiddleware())
    );
    
    initMessageListener(store);
     
    const persistor = persistStore(store);
    export {store , persistor};
    

    please see this link for more info!