I am trying to implement redux 4.0.0 with redux-persist 5.10.0 in an SSR application and am running into an issue where I cannot properly supply createStore()
with the preloaded state without the app crashing.
What happens is that the application loads with the initial state from the server, but when the app tries to preload the state in createStore()
on the client, the app refreshes and crashes. I assume it's because my preloadedState is not in the proper format?
But I'm not sure because I'm not getting any error messages in the console, the UI, nada.
Here is some relevant code:
store/index.js
export default function configureStore(preloadedState = {}) {
// This will store our enhancers for the store
const enhancers = [];
// Add thunk middleware
const middleware = [thunk];
// Apply middlware and enhancers
const composedEnhancers = compose(
applyMiddleware(...middleware),
...enhancers
);
// Set up persisted and combined reducers
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Create the store with the persisted reducers and middleware/enhancers
const store = createStore(persistedReducer, preloadedState, composedEnhancers);
const persistor = persistStore(store, null, () => {
store.getState(); // if you want to get restoredState
});
return { store, persistor };
}
index.js
const preloadedState = window.__PRELOADED_STATE__ ? window.__PRELOADED_STATE__ : {};
delete window.__PRELOADED_STATE__;
// Create redux store
const { persistor, store } = configureStore(preloadedState);
// Get app's root element
const rootEl = document.getElementById("root");
// Determine if we should use hot module rendering or DOM hydration
const renderMethod = !!module.hot ? ReactDOM.render : ReactDOM.hydrate;
renderMethod(
<Provider store={store}>
<PersistGate loading={<Loader />} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>,
rootEl
);
Things persist and whatnot in development on the client, but when I test the SSR the app loads, and then reloads and goes blank. It reloading has me thinking the state is not being hydrated with the same data. it crashing completely has me baffled at the moment.
Any idea of how to proceed??
EDIT
After some old-school debugging, I've found that removing the <PersistGate loading={<Loader />} persistor={persistor}>
line will allow the app to load initially and things are loaded via the server as expected, but the data does not persist properly (obviously).
Is there anything wrong with how I'm using the PersistGate
component?
window.__PRELOADED_STATE__
{
user: {…}, banners: {…}, content: {…}, locations: {…}, news: {…}, …}
banners: {isLoading: 0, banners: Array(2)}
content: {isLoading: 0, errors: {…}, data: {…}}
locations: {countries: Array(0), provinces: Array(0), default_country: null, isLoading: false, error: null, …}
news: {isLoading: 0, hasError: 0}
phoneTypes: {isLoading: false}
profileStatuses: {isLoading: false}
profileTypes: {isLoading: false}
reviewers: {isLoading: false}
route: {}
salutations: {isLoading: false}
sectors: {isLoading: false, sectors: Array(0)}
siteInfo: {pageTitle: "", isLoading: 0, hasError: 0, error: "", site: {…}, …}
sort: {value: "", dir: ""}
user: {isLoading: false, loginChecked: {…}, admin: null, reviewer: null, loginTokenLoading: false, …}
_persist: {version: -1, rehydrated: true}
__proto__: Object
}