我正在处理的应用程序基于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
});
答案 0 :(得分:0)
我已经对此问题进行了更深入的调查并找到了解决方案。 要实现DOM水合作用,以下几点应该是帐户中的标记:
我上面client.js
中的示例我曾两次调用createRoutes(store)
。这是多余的,因为renderProps
已为routes
组件准备了<Route />
属性。由于这个错误onEnter
被调用了两次,所以数据提取也被执行了两次。
为了避免服务器和客户端上的HTML不匹配,不应在第一个客户端呈现中调用onEnter
中的数据提取。
match
函数等待getComponent
回调。所以主要问题是错误的,因为这个功能是开箱即用的。