天天看點

每日分享- 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' 目錄中已經打包好的用戶端代碼。

繼續閱讀