天天看点

每日分享- React 程序中如何实现同构模板

同构模板是指在服务器端和客户端都能够渲染的模板,也称为“服务器端渲染”(Server-side Rendering, SSR)。在 React 中,同构模板可以通过将 React 组件在服务器端渲染为 HTML 字符串,然后在客户端再次渲染为 React 组件来实现。这样可以提高网站的首屏加载速度和 SEO 优化效果。

以下是几种常见的实现同构模板的方法:

  • React 服务器端渲染模块(React Server Rendering Module):React 官方提供了一个名为 ReactDOMServer 的模块,可以将 React 组件渲染为 HTML 字符串。可以在服务器端调用该模块,将组件渲染为 HTML 字符串,然后将字符串传输到客户端。

    以下是一个使用 React 服务器端渲染模块的示例代码,它将组件渲染为 HTML 字符串,然后将字符串传输到客户端:

import ReactDOMServer from 'react-dom/server';

const App = () => {
  return <div>Hello, World!</div>;
};

const html = ReactDOMServer.renderToString(<App />);
console.log(html);           
  • Next.js:Next.js 是一个基于 React 的服务器端渲染框架。它提供了一套完整的解决方案,包括服务器端渲染、代码分割、静态资源预加载等。使用 Next.js 可以轻松地实现同构模板。

    以下是一个使用 Next.js 的示例代码,它实现了服务器端渲染和客户端渲染的同构模板:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { hydrate } from 'react-dom';
import { useRouter } from 'next/router';

const IndexPage = () => {
  const router = useRouter();
  return (
    <div>
      <h1>Next.js</h1>
      <button onClick={() => router.push('/about')}>Go to About</button>
      <App />
    </div>
  );
};

if (typeof window !== 'undefined') {
  ReactDOM.render(<IndexPage />, document.getElementById('root'));
} else {
  hydrate(<IndexPage />, document.getElementById('root'));
}           
  • Gatsby:Gatsby 是一个基于 React 的静态网站生成器。它使用 GraphQL 查询数据,并将数据预取到页面中。Gatsby 支持服务器端渲染和静态网站生成,可以帮助开发者实现同构模板。

    以下是一个使用 Gatsby 的示例代码,它实现了服务器端渲染和静态网站生成的同构模板:

import React from 'react';
import { graphql } from 'gatsby';

const BlogPost = ({ data }) => {
  const post = data.markdownRemark;
  return (
    <div>
      <h1>{post.frontmatter.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.html }} />
    </div>
  );
};

export const query = graphql`
  query BlogPostQuery($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      frontmatter {
        title
      }
      html
    }
  }
`;

export default BlogPost;           
  • create-react-app:create-react-app 是一个用于创建 React 应用程序的脚手架工具。它提供了服务器端渲染的支持,可以通过配置实现同构模板。

    以下是一个使用 create-react-app 的示例代码,它通过配置实现了服务器端渲染的同构模板:

// server.js
const express = require('express');
const React = require('react');
const ReactDOMServer = require('react-dom/server');
const { StaticRouter } = require('react-router-dom');
const App = require('./src/App').default;

const app = express();

app.use(express.static('build'));

app.get('*', (req, res) => {
  const context = {};

  const html = ReactDOMServer.renderToString(
    <StaticRouter location={req.url} context={context}>
      <App />
    </StaticRouter>
  );

  if (context.url) {
    res.redirect(context.url);
  } else {
    res.send(`
      <!DOCTYPE html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>React SSR Example</title>
        </head>
        <body>
          <div id="root">${html}</div>
          <script src="/static/js/main.js"></script>
        </body>
      </html>
    `);
  }
});

app.listen(3000, () => {
  console.log('Server is listening on port 3000');
});           

在上面这个示例中,我们首先使用 'StaticRouter' 将路由信息传递给 React 组件,然后使用 'ReactDOMServer.renderToString' 方法将 React 组件渲染为 HTML 字符串。最后,将生成的 HTML 字符串和客户端代码一起发送到客户端,客户端代码通过使用 'ReactDOM.hydrate' 方法将 HTML 字符串转换回 React 组件,从而完成客户端渲染的工作。注意,这里使用了 'build' 目录中已经打包好的客户端代码。

继续阅读