搭建渲染服务器

基于 Express 的渲染服务器

renderToString

React 提供了两个方法 renderToStringrenderToStaticMarkup 用来将组件(Virtual DOM)输出成 HTML 字符串,这是 React 服务器端渲染的基础,它移除了服务器端对于浏览器环境的依赖,所以让服务器端渲染变成了一件有吸引力的事情。这两个方法被包含在了 react-dom 仓库中,可以通过如下方式引入与使用:

import ReactDOMServer from "react-dom/server";

var ReactDOMServer = require("react-dom/server");

ReactDOMServer.renderToString(element);

我们可以在服务端即使用renderToString将组件转化为 HTML 标签然后传递给客户端,这里 React 会自动为标签进行校验和计算;这样我们在客户端调用 ReactDOM.render() 渲染某个组件时,如果 React 发现已经存在了服务端渲染好的标签,则会直接使用这些标签来节约渲染时间。ReactDOMServer 中提供的另一个渲染函数是renderToStaticMarkup,其很类似于renderToString,不过其忽略了额外的譬如data-reactid这样的 React 内部使用的非 HTML 标准属性;如果你只想把 React 作为简单的静态网页生成器,那么推荐使用这种方式,会帮你避免额外的带宽消耗。

服务器端渲染除了要解决对浏览器环境的依赖,还要解决两个问题:

  • 前后端可以共享状态

  • 前后端路由可以统一处理

状态传递

路由权限控制

import { renderToString } from "react-dom/server";
import { match, RouterContext } from "react-router";
import routes from "./routes";

serve((req, res) => {
  // Note that req.url here should be the full URL path from
  // the original request, including the query string.
  match(
    { routes, location: req.url },
    (error, redirectLocation, renderProps) => {
      if (error) {
        res.status(500).send(error.message);
      } else if (redirectLocation) {
        res.redirect(302, redirectLocation.pathname + redirectLocation.search);
      } else if (renderProps) {
        // You can also check renderProps.components or renderProps.routes for
        // your "not found" component or route respectively, and send a 404 as
        // below, if you're using a catch-all route.
        res
          .status(200)
          .send(renderToString(<RouterContext {...renderProps} />));
      } else {
        res.status(404).send("Not found");
      }
    }
  );
});

基于 Next.js 快速搭建渲染服务器

上一页
下一页