我刚开始学习ReactJS,发现它可以提供两种页面渲染方式:服务器端和客户端。但是,我不理解如何同时使用它们两个。这是两种分开构建应用的方式,还是可以同时使用它们两个?
如果我们可以同时使用它们,那么应该怎样做呢?需要在服务器端和客户端都复制相同的元素吗?还是只需在服务器端构建应用的静态部分,在客户端构建动态部分,而不与已经预渲染的服务器端进行任何连接?
我刚开始学习ReactJS,发现它可以提供两种页面渲染方式:服务器端和客户端。但是,我不理解如何同时使用它们两个。这是两种分开构建应用的方式,还是可以同时使用它们两个?
如果我们可以同时使用它们,那么应该怎样做呢?需要在服务器端和客户端都复制相同的元素吗?还是只需在服务器端构建应用的静态部分,在客户端构建动态部分,而不与已经预渲染的服务器端进行任何连接?
componentWillMount()
中不应进行任何异步数据获取,因为它将在客户端和服务器上运行。您还需要一种策略,在服务器上预先获取数据并使其可用于客户端的初始呈现,以确保获得相同的输出。 - Jonny Buchanantypeof window == "undefined"
来检查正在执行的代码是在服务器端还是客户端,然后相应地获取您的数据。 - Gautham Badhrinathan<div>
。 - Matt Holland图片来源: 沃尔玛实验室工程博客
NB:SSR(服务器端渲染)、CSR(客户端渲染)。
最主要的区别在于,使用 SSR 时,服务器响应客户端浏览器时,会包含待渲染页面的 HTML。 值得注意的是,虽然使用 SSR 可以更快地呈现页面,但在 JS 文件被下载并且浏览器执行 React 之前,页面将无法进行用户交互。
一个缺点是 SSR 的 TTFB(首字节时间)可能会稍长。这是可以理解的,因为服务器需要一些时间来创建 HTML 文档,从而增加了服务器响应的大小。
我其实也在研究同样的问题,查了很多资料。虽然评论中已经给出了你要找的答案,但我觉得它应该更加突出,因此我写下了这篇文章(一旦我能想出更好的解决方案,我会更新它,因为我认为当前的解决方案至少存在一些问题)。
你需要编写组件时要考虑两种方式,基本上到处都要放置if
开关来确定你是在客户端还是服务器端,然后根据情况进行数据库查询(或其他适当的服务器操作)或REST调用(在客户端)。接着,你需要编写端点来生成数据并将其暴露给客户端,就可以了。
如果有更简洁的解决方案,欢迎分享。
const app = Express();
const port = 8092;
// This is fired every time the server side receives a request
app.use(handleRender);
function handleRender(req, res) {
const fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
console.log('fullUrl: ', fullUrl);
console.log('req.url: ', req.url);
// Create a new Redux store instance
const store = createStore(reducerFn);
const urlToRender = req.url;
// Render the component to a string
const html = renderToString(
<Provider store={store}>
<StaticRouter location={urlToRender} context={{}}>
{routes}
</StaticRouter>
</Provider>
);
const helmet = Helmet.renderStatic();
// Grab the initial state from our Redux store
const preloadedState = store.getState();
// Send the rendered page back to the client
res.send(renderFullPage(helmet, html, preloadedState));
}
我给刚开始学习SSR的人的建议是提供静态HTML。您可以通过运行CSR SPA应用程序来获取静态HTML:
document.getElementById('root').innerHTML
不要忘记,使用SSR的唯一原因应该是:
技巧:https://medium.com/@gagan_goku/react-and-server-side-rendering-ssr-444d8c48abfc