s-s-r:反应应用程序中的动态导入如何在客户端加载组件时处理html未匹配

Posted

技术标签:

【中文标题】s-s-r:反应应用程序中的动态导入如何在客户端加载组件时处理html未匹配【英文标题】:s-s-r: dynamic import in react app how to deal with html miss match when component is loading on the client 【发布时间】:2019-04-11 05:38:16 【问题描述】:

感谢 webpack 4 和 react-loadable,我刚刚开始使用代码拆分和动态导入在服务器端渲染一个 react 16 应用程序。

我的问题可能听起来很愚蠢,但有些东西我不太明白。

在服务器端,我正在等待 webpack 已加载所有模块,然后再将 html 吐出给客户端。

在客户端,我在渲染加载的组件之前渲染了一种加载组件。

所以基本上服务器渲染加载的组件:

<div>loaded component</div>

客户端水合加载组件:

<div>loading...</div>

很明显,问题是 React 在 hydra() 之后抱怨,因为服务器和客户端之间存在不匹配。

在几秒钟内,客户端首先呈现

<div>loading...</div>

而服务器已经渲染并发送到客户端,加载组件的 html。

有人可以启发我吗?它是如何工作的? 加载组件时如何防止第一次渲染不匹配?

【问题讨论】:

【参考方案1】:

看起来您没有预加载您的客户端中的同意。

Loadable.preloadReady().then(() => 
  ReactDOM.hydrate(<App/>, document.getElementById('app'));
);

这也是avoidhydration mismatch 的必需步骤。

原因:

此问题是在您的客户端上引起的,因为初始请求,您的 chunks 未加载,因此这些组件的 html output 将是 loading... 而不是 component content 本身。 只有在获取并加载块后,此初始状态 loading... 才会被所需的内容替换。

所以,Loadable.preloadReady 方法会创建一个 Promise,一旦预加载应用程序块,resolved 将具有初始阶段所需的所有资产,ReactDOM.hydrate 将生成与您的相同的输出服务器做到了。


提示

另外我建议你看看React Loadable s-s-r Add-on,这是一个非常方便的add-on,它将增强你的服务器端资产管理,给你带来与CSR(客户端渲染)相同的好处。

React Loadable 的服务器端渲染插件。加载拆分的块从未如此简单。

见https://github.com/themgoncalves/react-loadable-s-s-r-addon

【讨论】:

Goncalves 我会在客户端上预加载块。我发现 __webpack_modules__[moduleId] 始终未定义,因此不会发生 resolveWeak。您可以在那里重现该问题:github.com/jaybe78/react-loadable。 这对我来说仍然很困惑,但据我了解,resolveWeak 与 import 结合使用,将允许在组件加载后同步渲染客户端上的块,而不会出现不匹配的情况发生。因为基本上在客户端初始渲染时,它会渲染 这与服务器渲染的不同,但随后它会再次渲染(这次是可加载组件),这就是 resolveWeak 同步渲染的作用客户端。对吗!? @jaybe78 你是否也导入了react-loadable/babel .babelrc 插件配置?基本上这期resolveWeakloadable configuration有关。 react-loadable的正确使用方式如下: Loadable( loader: () => import('./Bar'), modules: ['./Bar'], webpack : () => [require.resolveWeak('./Bar')], );但是如果你只是将react-loadable/babel添加到你的babel配置中,你不必每次都指定moduleswebpack键,它会被这个插件自动处理。文档:github.com/jaybe78/…

以上是关于s-s-r:反应应用程序中的动态导入如何在客户端加载组件时处理html未匹配的主要内容,如果未能解决你的问题,请参考以下文章

Next.js:如何将仅外部客户端的 React 组件动态导入到开发的服务器端渲染应用程序中?

在 s-s-r 上的反应组件中导入 scss

如何将 React s-s-r 应用程序部署到 Heroku?

在反应中动态导入模块

如何在反应应用程序中动态导入moment.js(使用打字稿)

使用 cypress.io 模拟 s-s-r 反应应用程序 e2e 测试的服务器