React 18 提出和支持了 Suspense SSR 的概念:页面中数据请求耗时较长的组件,可以流式返回,并被延迟 Hydrate
参考 React 的 官方 Demo , ICE 也对应跑了一个 Demo https://github.com/ice-lab/ice-next/pull/645/files
暴露的问题是:流式返回的组件,如何回传对应的数据给 Client,用于 Hydrate?
假设 Comments
是一个有数据请求,并被流式返回的组件
<Suspense fallback={<div>Loading...</div>}>
<Comments />
</Suspense>
Comments
内部做了数据请求,请求未完成时,页面渲染的为 Loading 状态
export default function Comments() {
const comments = useData();
return (
<>
{comments.map((comment, i) => (
<p className="comment" key={i}>
{comment}
</p>
))}
</>
);
}
我们知道 SSR 时,Server 传递给 Client 端的内容为 html 片段,当 Client 接受到 html 后,会基于 数据
和 JS Bundle
, 重新创建 VDom,进行 Hydrate。
Suspense SSR
下, Comments
的 html 片段是由 React 控制返回的,然后 React 并没有对应的返回 Comments
需要消费的数据,因此 Client 端是无法进行 Hydrate 的。
在 React 的 官方 Demo , Comments
在 Client 端消费的是一份写死数据(也就是说被构建到 Bundle 中)
React 的 RFC 下也有人提到了这个问题,reactwg/react-18#37 (comment)
sebmarkbage 给的解决方案是可以通过 embedded script tags
来传递,但在 React 的 html 流之外,如何追加额外 script 标签似乎也不容易。
1条答案
按热度按时间1cklez4t1#
所以合理的方式应该就是结合 server component 进行处理?