将 hydrate() 与异步一起使用。组件

Use hydrate() with async. components

我正在开发的应用程序基于 React Fiber 和 React Router V3。

尝试使用 hydrate() 而不是 render()async components 我遇到了以下问题:从 SSR 返回的 HTML 与客户端不同.

结果 React 重新挂载整个 DOM 并抛出以下警告:Did not expect server HTML to contain....

React Training 也没有提供解决方案:Code-splitting + server rendering

有什么解决办法吗?

更新:

简单示例

(伪代码)

App.js:

export default () => <div>Lorem Ipsum</div>;

client.js:

const createRoutes = store => ({
  path: '/',
  getComponent(nextState, cb) {
    require('./App'); // some async require
  },
  onEnter: (nextState, replace, cb) => {
    store.dispatch(fetchData())
      .then(() => cb())
      .catch(cb);
  }
});

match({history, routes: createRoutes(store)},
  (error, redirectLocation, renderProps) => {
  hydrate(
    <Router history={history} routes={createRoutes(store)} />,
    document.getElementById('app')
  );
});

server.js

match({routes: createRoutes(store), location: req.url},
  (err, redirectLocation, renderProps) => {
  const content = renderToString(<RouterContext {...renderProps}/>);
  // send content to client
});

我更深入地调查了这个问题并找到了解决方案。 要实现 DOM 水合作用,应考虑以下几点:

  1. 我在上面的例子 client.js 中调用了 createRoutes(store) 两次。这是多余的,因为 renderProps 已经为 <Route /> 组件准备了 routes 属性。由于这个错误onEnter被调用了两次,所以数据也被执行了两次。

  2. 为避免 HTML 服务器端和客户端数据获取不匹配 onEnter 不应在第一个客户端渲染时调用。

  3. match 函数等待 getComponent 回调在渲染之前执行。所以主要问题是错误的,因为这个功能是开箱即用的。