1

我正在创建一个 React SSR 项目。我已经集成了 Redux 实现了服务器端渲染。但是,当我使用带有批量数据的 api 浏览某个组件时,在加载时,点击浏览器的后退按钮,我的路线会立即更改,该组件的数据已加载,但在当前组件获取其数据之前不会显示,并且渲染它。

那么有什么方法可以在 url 更改时停止异步节点服务器端调用数据,即使该异步数据尚未到来?我现在正在使用axios

这是我的服务器渲染:

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);
    });
  };
}

这是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'),
);

这是一个容器,它具有获取数据的静态方法。服务端调用匹配Container的fetchData

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);
  }
}
4

0 回答 0