使用hydrate()与异步。组件

时间:2018-01-24 16:36:19

标签: javascript reactjs webpack react-router react-fiber

我正在处理的应用程序基于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
});

1 个答案:

答案 0 :(得分:0)

我已经对此问题进行了更深入的调查并找到了解决方案。 要实现DOM水合作用,以下几点应该是帐户中的标记:

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

  2. 为了避免服务器和客户端上的HTML不匹配,不应在第一个客户端呈现中调用onEnter中的数据提取。

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