-2

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

尝试使用异步组件hydrate()而不是异步组件时,我遇到了以下问题:从 SSR 返回的 HTML 与客户端不同。render()

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

React Training 也不提供解决方案:代码拆分 + 服务器渲染

有什么解决方案可以实现这一目标吗?

更新:

简单示例

(伪代码)

应用程序.js:

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

客户端.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')
  );
});

服务器.js

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

1 回答 1

1

我已经对该问题进行了更深入的调查并找到了解决方案。要实现 DOM 水合,应考虑以下几点:

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

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

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

于 2018-01-28T07:30:30.757 回答