React服务端渲染是指把React组件在服务端渲染成HTML字符串,然后再把这些HTML字符串发送给客户端展示,这种渲染方式能够在很大程度上提升页面的渲染速度和SEO友好性。
下面我们将详细讲解React服务端渲染的完整攻略,它主要包括以下步骤:
步骤一:安装依赖
首先,我们需要安装React和React DOM以及相关的babel插件:
npm install react react-dom @babel/core @babel/preset-react babel-loader express
其中,@babel/preset-react 主要用于将JSX编译成JavaScript代码。
步骤二:创建服务端文件
接着,我们需要在项目根目录下创建一个 server.js 文件,用于处理服务端渲染的逻辑。代码如下:
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './src/App';
const server = express();
server.use(express.static('public'));
server.get('/', (req, res) => {
const app = ReactDOMServer.renderToString(<App />);
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>React SSR</title>
</head>
<body>
<div id="root">${app}</div>
<script src="./bundle.js"></script>
</body>
</html>
`);
});
server.listen(8080, () => {
console.log('Server is running on http://localhost:8080');
});
这段代码首先会使用 express 创建一个 HTTP 服务器,并且将 public 目录暴露出来,之后,我们使用 ReactDOMServer.renderToString() 方法将 App 组件渲染成 HTML 字符串。
最后,我们将生成的 HTML 字符串插入到 HTML 模板中,最终返回给客户端。需要注意的是,我们还需要在 HTML 模板中添加置入客户端代码的占位符。
步骤三:创建客户端文件
在创建了服务端文件后,我们还需要创建一个客户端文件,用于渲染 React 组件并附加事件等逻辑。代码如下:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './src/App';
ReactDOM.hydrate(<App />, document.getElementById('root'));
这里,我们使用 ReactDOM.hydrate() 方法对 App 组件进行渲染,同时还需要将其插入到服务端渲染生成的 HTML 文件中,之后再将生成的 JS 文件引入到 HTML 模板中。
步骤四:配置打包工具和脚本
最后,我们还需要配置打包工具和脚本,使得我们的服务端代码和客户端代码能够打包成单独的文件并在启动时正确加载。这里以 webpack 为例,示例代码如下:
const path = require('path');
module.exports = {
mode: 'production',
entry: './index.js',
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react'],
},
},
},
],
},
};
再用如下 script 命令来启动打包:
npx webpack --config webpack.config.js
至此,我们的 React 服务端渲染应用已经完成了,可以使用 npm start 启动项目并在浏览器中访问 http://localhost:8080 进行查看。
下面以 React服务端渲染购物车为例,进行演示:
示例一:购物车列表页
服务端代码:
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './src/App';
import path from 'path';
import fs from 'fs';
const server = express();
server.use(express.static(path.resolve(__dirname, '..', 'build')));
server.get('/', (req, res) => {
const app = ReactDOMServer.renderToString(<App />);
const html = fs.readFileSync(
path.resolve(__dirname, '..', 'build', 'index.html'),
'utf-8'
);
res.send(
html.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
);
});
server.listen(8080, () => {
console.log('Server is running on http://localhost:8080');
});
客户端代码:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './src/App';
ReactDOM.hydrate(<App />, document.getElementById('root'));
示例二:购物车详情页
服务端代码:
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './src/Detail';
import path from 'path';
import fs from 'fs';
const server = express();
server.use(express.static(path.resolve(__dirname, '..', 'build')));
server.get('/:id', (req, res) => {
const app = ReactDOMServer.renderToString(<App id={req.params.id} />);
const html = fs.readFileSync(
path.resolve(__dirname, '..', 'build', 'index.html'),
'utf-8'
);
res.send(
html.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
);
});
server.listen(8080, () => {
console.log('Server is running on http://localhost:8080');
});
客户端代码:
import React from 'react';
import ReactDOM from 'react-dom';
import Detail from './src/Detail';
ReactDOM.hydrate(<Detail id={window.__PRELOADED_STATE__.id} />, document.getElementById('root'));
此外,还需要在服务端代码中增加对静态资源的处理。这里我们使用了 Express 框架提供的 express.static() 方法,将构建好的静态资源目录(build)暴露给客户端。
server.use(express.static(path.resolve(__dirname, '..', 'build')));
以上就是React服务端渲染的完整攻略,并且包含了两个示例的说明,供大家进行参考。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:React服务端渲染(总结) - Python技术站