1

I'm creating a React SSR Project. I have achieved server-side rendering with Redux integrated. However When I go through some component using api with bulk data, then while it's loading, hit the Back button of browser, my route changes immediately, the data of that component is loaded but it is not displayed until the current component gets its data and renders it.

So Is there any way to stop the async node server-side calling the data, as soon as the url changes, even if that async data hasn't come yet? I am using axios for now.

This is my server render:

export default function serverRenderer({ clientStats, serverStats }) {
  return (req, res, next) => {
    const context = {};
    const pageContainer = req.pageContainer || {};
    const PAGE = pageContainers.default[pageContainer];
    if (!PAGE || typeof (PAGE.fetchData) !== 'function') {
      const markup = ReactDOMServer.renderToString(
        <Provider store={store}>
          <StaticRouter location={req.url} context={context}>
            <RouteComp />
          </StaticRouter>
        </Provider>,
      );
      const helmet = Helmet.renderStatic();
      return res.status(200).send(Template({
        markup,
        helmet,
        state: store.getState(),
      }));
    }
    return PAGE.fetchData(store, req.urlparams).then(() => {
      const markup = ReactDOMServer.renderToString(
        <Provider store={store}>
          <StaticRouter location={req.url} context={context}>
            <RouteComp />
          </StaticRouter>
        </Provider>,
      );
      const helmet = Helmet.renderStatic();
      res.status(200).send(Template({
        markup,
        helmet,
        state: store.getState(),
      }));
    }).catch((e) => {
      console.log('fetch data error:::', e);
    });
  };
}

This is client.js

// Grab the state from a global variable injected into the server-generated HTML
const preloadedState = window.__PRELOADED_STATE__;

// Allow the passed state to be garbage-collected
delete window.__PRELOADED_STATE__;

// Create Redux store with initial state
const store = createStore(reducer, preloadedState, applyMiddleware(thunk));

hydrate(
  <Provider store={store}>
    <BrowserRouter>
      <RouteComp />
    </BrowserRouter>
  </Provider>,
  document.getElementById('app'),
);

This is a container which would have a static method for fetching data. The server calls fetchData of the matched Container

class HomeContainer extends Component {
  static fetchData(store) {
    const promises = [
      store.dispatch(fetchHomePageStarted()),
      getHomePageData()
        .then((response) => {
          const { data } = response;
          return store.dispatch(fetchHomePageSuccess(data));
        })
        .catch((error) => {
          console.log('error occurred -> ', error);
          return store.dispatch(fetchHomePageFailed(error));
        }),
    ];
    return Promise.all(promises);
  }
}
akhtarvahid
  • 9,445
  • 2
  • 26
  • 29
Ravi Garg
  • 1,378
  • 12
  • 23
  • 1
    Can you show some example code? – airsoftFreak Dec 07 '19 at 05:13
  • @airsoftFreak I have added some core methods. Might help you. – Ravi Garg Dec 07 '19 at 05:21
  • To make sure I understand, route 1 has component A which starts fetching some data, then you press back to route 2 that has component A & B, and although A's data has loaded already it doesn't show up until B's data is ready? Also why HomeContainer extends Component? – adamz4008 Dec 07 '19 at 06:42
  • Yes, @adamz4008 You understood it correctly. The Component it is extending is actually React.Component. – Ravi Garg Dec 07 '19 at 07:43
  • @spycbanda Why does it extend `React.Component` if it doesn't appear to be an actual React component with a render method? And just a class with one static method. I'm not sure what the async node code would have to do with this. Correct me if I'm wrong, but It looks like when user requests the initial route, the data for that route is fetched, and THEN sent to the client, and once the first route is sent back, SSR is not used, but only SPA navigation. So I would think the problem would be in your (client) router code, try posting that if there's still an issue, you might get more help on it. – adamz4008 Dec 12 '19 at 04:04
  • Did you get a solution to this problem as I am facing the same issue – Vipin Yadav May 23 '20 at 09:45

0 Answers0