Server side store does not update after a dispatch

251 Views Asked by At

I have a server side rendering react app made with razzle in typescript. This is what I want to achieve. I want the server to get authenticated data before rendering any page in my app, dispatch it to the store and then insert it on the rendered document for the client to pickup and use in a store.

I have made it possible to run on dispatch actions for particular routes using react-router-config and promises and every requests are made through axios.

my store

import { createStore, applyMiddleware, compose } from "redux";
import promiseMiddleware from "redux-promise-middleware";
import { composeWithDevTools } from "redux-devtools-extension";
import thunkMiddleware from "redux-thunk";
import reducer, { IRootState } from "./root.reducer";
import notificationMiddleware from "config/notification-middleware";
import loggerMiddleware from "config/logger-middleware";
import loadingBarMiddleware from "config/loading-bar-middleware";

const defaultMiddlewares = [
  thunkMiddleware,
  notificationMiddleware,
  promiseMiddleware,
  loadingBarMiddleware,
  loggerMiddleware,
];
const composedMiddlewares = (middlewares: any) =>
  process.env.NODE_ENV === "development"
    ? composeWithDevTools(
        applyMiddleware(...defaultMiddlewares, ...middlewares)
      )
    : compose(applyMiddleware(...defaultMiddlewares, ...middlewares));

const initialize = (initialState?: IRootState, middlewares = []) => createStore(reducer, initialState, composedMiddlewares(middlewares));

export default initialize;

action of getSession

export const getSession: any = () => async (dispatch: any) => {
  await dispatch({
    type: ACTION_TYPES.GET_SESSION,
    payload: axios.get("api/account")
  })
};

server.ts

import renderApp from "server/renderer";

const Routes = [
  {
    path: "/",
    component: Home,
    loadData: (dispatch: ThunkDispatch<IRootState, void, Action<any>>) => dispatch(getSession()),
  },
  // etc.
];

// Create a new Redux store instance
const store = initStore();

const { dispatch } = store;

const actions = bindActionCreators({ clearAuthentication }, dispatch);
setupAxiosInterceptors(() => actions.clearAuthentication("Unauthorized action"), Cookies.load("jhi-authenticationToken", req));

const routes = matchRoutes(Routes, req.path);

const promises = routes.map(({ route }: any) =>
  route.loadData instanceof Function ? route.loadData(dispatch) : Promise.resolve()
);

Promise.all(promises).then(() => {
  renderApp(store, req, res);
});

renderer.tsx // Grab the initial state from our Redux store

import serialize from "serialize-javascript";

const finalState = store.getState();

const markup = renderToString(
      <StaticRouter context={context} location={req.url}>
        <Provider store={store}>
          <App />
        </Provider>
      </StaticRouter>
    )
  );
  
res.status(200).send(`<!DOCTYPE html>
              <html lang="fr">
                <head>
                  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                  <meta charset="utf-8" />
                </head>
                <body>
                  <div id="root">${markup}</div>
                  <script>
                    window.__PRELOADED_STATE__ = ${serialize(finalState)};
                  </script>
                </body>
              </html>`
      )
    );
  }
};

But my store does not update and I still have the same data from the initial state.

Note

  • I checked the rendered HTML the browser and it is the initial state that I receive
  • It seems like these actions does not update my states as I inserted some console.logs in reducers and no log appeared on the terminal
  • getSession works well on the client.
0

There are 0 best solutions below