Initialstate gets corrupted/cached on server side for concurrent requests
See original GitHub issueDescribe the bug
The app requests multiple endpoints and uses an identifier to get the data. This identifier, catalog ID, is set in _app.js after looking at incoming request. Once the catalog ID is identified a store.dispatch is sent and catalog ID is set in an object named appConfigs server side store. All the components get catalog id from server side store and use this to different backend calls. This works perfectly fine when the apps is browsed one page at a time. As soon as more than 3 concurrent calls are sent, the catalog id on server side gets mixed up. This causes initialstate to be corrupted and subsequently client side hydration is also mixed up when client side store is hydrated with this corrupted data.
Here is how the store is being created and then used in _app.js
// store.js
/* eslint-disable no-underscore-dangle */
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import createSagaMiddleware from "redux-saga";
import reducers from "../reducers/index";
import rootSaga from "../sagas/rootSaga";
const isDev = process.env.NODE_ENV === "development";
const isServer = typeof window === "undefined";
const sagaMiddleware = createSagaMiddleware();
const middleWares = [sagaMiddleware];
if (isDev && !isServer) {
middleWares.push(logger);
}
let initialState = {};
if (!isServer && window.document && window.__NEXT_DATA__) {
initialState = window.__NEXT_DATA__.props.initialState;
delete window.__NEXT_DATA__;
}
const store = createStore(reducers, initialState, applyMiddleware(...middleWares));
sagaMiddleware.run(rootSaga);
export default store;
//_app.js only posting/pasting relevant code
import App from "next/app";
import React from "react";
import { Provider } from "react-redux";
import { createWrapper } from "next-redux-wrapper";
import store from "./store";
class BasePage extends App {
static async getInitialProps({ Component, ctx }) {
/*
Logic to find following
rootGeoId: country,
catalogue,
category,
*/
ctx.store.dispatch({
type: APP_CONSTANTS.SET_APP_CONFIGS,
payload: {
rootGeoId: country,
catalogId: catalogue,
category,
},
});
const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {};
return {
country,
configs,
pageProps,
path: ctx.asPath,
};
}
render() {
// logic for renderLayout
return (
<ThemeProvider theme={theme}>
<Provider store={store}>
{renderLayout}
</Provider>
</ThemeProvider>
);
}
}
const makeStore = () => store;
export default createWrapper(makeStore).withRedux(BasePage);
To Reproduce
You will need a way to click open multiple pages using mouse wheel click
- Visit https://uat.fnp.com/red-roses
- From Global menu, open “Women’s day” gift links using mouse wheel in new tabs.
- Visit tabs and look in initialStore for these pages using Components under react dev tools
- You will notice for some of the countries the catalogID in initialStore.appConfigs is not correct, for example, for UAE it can be UK.
Expected behavior
Every request should maintain its unique store. This is visible when you just browse the site/app one page at a time
Screenshots
Desktop (please complete the following information):
- OS: Any
- Browser Any
Additional context
Issue Analytics
- State:
- Created 2 years ago
- Reactions:6
- Comments:9 (4 by maintainers)
Top GitHub Comments
@fostyfost while @kirill-konshin responds to you, I will test your forked repo.
@kirill-konshin I think this problem is caused by this line https://github.com/kirill-konshin/next-redux-wrapper/blob/9b041f8258745f2402a88f542dd379eae37a8220/packages/wrapper/src/index.tsx#L47 I sent you PR https://github.com/kirill-konshin/next-redux-wrapper/pull/394