Search code examples
javascriptreact-reduxredux-persist

How to fetch from server on Redux Rehydrate?


I'm using React/Redux and redux-persist to maintain local storage persistence. I'm looking to load an 'appSettings.json' from the server when redux-persist has finished Rehydrating the store from local storage.

In the persistStore method there is a callback function that is guaranteed to come after the store has been rehydrated, but I then need to make a server call to fetch the appSettings.json.

Is there a way in which I can await the fetch until the server responds?

I require the API URL from the appSettings.json in order to make API calls, but the calls from within the components are occurring before the appSettings fetch has returned.

const persistor = persistStore(store, persistConfig, async () => {

return await fetch('settings.json')
    .then(response => {
        return response.json();
    })
    .then(data => {
        console.log(data);
        store.dispatch({ type: "API_BASE_RESPONSE",  base_api_url: data.baseApiUrl });
    })

});

I've tried a few different variations of awaiting but with no luck. Is there perhaps an even better method of doing what I'm trying to achieve?


Solution

  • Managed to resolve (for now) this by adding a method to the PersistGate of redux-persist.

    const onBeforeLift = async () => {
    
        // take some action before the gate lifts
        return await fetch('settings.json')
            .then(response => {
                return response.json();
            })
            .then(data => {
                console.log(data);
                store.dispatch({ type: "API_BASE_RESPONSE",  base_api_url: data.baseApiUrl });
            })
    }
    
    ReactDOM.render((
        // specify basename below if running in a subdirectory or set as "/" if app runs in root
        <Provider store={store}>
            <PersistGate 
                onBeforeLift={onBeforeLift}
                persistor={persistor}>
                <BrowserRouter basename={WP_BASE_HREF}>
                    <Routes />
                </BrowserRouter>
            </PersistGate>
        </Provider>
    
    ), document.getElementById('app'))