S. *_*ong 6 javascript reactjs server-side-rendering styled-components react-helmet
我试图做SSR与ReactDOMServer.renderToNodeStream(element)只是想知道是否有将与同时使用的任何问题ReactDOMServer.renderToString(element),并 ReactDOMServer.renderToNodeStream(element)在每个请求?
我在自定义 SSR 设置中拥有的是:* React 16 * react-loadable * styled-components v4 * react-helmet-async * Redux * Express JS
以前使用 React,我可以通过首先渲染<head></head>包含由React生成的标记的标签,react-helmet然后使用它ReactDOMServer.renderToString()来渲染我的 React 元素来轻松渲染 HTML 文档。
但是,通过切换到ReactDOMServer.renderToNodeStream()我不得不切换react-helmet为react-helmet-async,它支持renderToNodeStream()功能。但是当我尝试<head></head>用标记渲染标签时,react-helmet-async它会返回为undefined.
为了解决这个问题,我不得不先使用,renderToString()而没有将它实际写到 Express JS 中response。这样react-helmet-async就可以看到要呈现哪些元标记,然后继续使用renderToNodeStream并将其流式传输到response.
我已经尽可能地简化了我的代码,因为我想了解这是否会产生负面影响(对于性能,或者是否有人能想到其他任何事情)?
前:
let html = ReactDOMServer.renderToString(stylesheet.collectStyles(
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
<LocalStoreProvider store={store}>
<HelmetProvider context={helmetContext}>
<RouterContext {...renderProps} />
</HelmetProvider>
</LocalStoreProvider>
</Loadable.Capture>
));
const { helmet } = helmetContext;
response.write(
renderDocumentHead({
css: stylesheet.getStyleTags(),
title: helmet.title.toString(),
link: helmet.link.toString(),
meta: helmet.meta.toString()
})
);
response.write(html);
Run Code Online (Sandbox Code Playgroud)
后:
let html = stylesheet.collectStyles(
<Loadable.Capture report={moduleName => modules.push(moduleName)}>
<LocalStoreProvider store={store}>
<HelmetProvider context={helmetContext}>
<RouterContext {...renderProps} />
</HelmetProvider>
</LocalStoreProvider>
</Loadable.Capture>
);
// do a first pass render so that react-helmet-async
// can see what meta tags to render
ReactDOMServer.renderToString(html);
const { helmet } = helmetContext;
response.write(
renderDocumentHead({
css: stylesheet.getStyleTags(),
title: helmet.title.toString(),
link: helmet.link.toString(),
meta: helmet.meta.toString()
})
);
const stream = stylesheet.interleaveWithNodeStream(
ReactDOMServer.renderToNodeStream(html)
);
// and then actually stream the react elements out
stream.pipe(response, { end: false });
stream.on('end', () => response.end('</body></html>'));
Run Code Online (Sandbox Code Playgroud)
不幸的是,只有这样我才能react-helmet-async正常工作,我必须进行两次渲染。我的 CSS 样式等正确解析,客户端也正确呈现/水合物。我已经看到其他示例,其中react-apollo使用了getDataFromTree数据再水化方法,它允许react-helmet-async查看渲染头部标记所需的内容。但希望我的两遍渲染方法没有问题?
| 归档时间: |
|
| 查看次数: |
1863 次 |
| 最近记录: |