路由支持
实现思路
在 React SSR 项目中需要实现两端路由:
-
客户端路由用于支持用户通过点击链接的形式跳转页面。
-
服务器端路由用于支持用户直接从浏览器地址栏中访问页面。
客户端和服务器端共用一套路由规则,所以路由规则代码属于同构代码。
新增一个页面
新增一个 List 页面用于测试路由切换:
// src\share\pages\List.js
import React from 'react'
function List() {
return <div>List works</div>
}
export default List
安装路由依赖
react-router-dom # react 路由模块
react-router-config # react 路由规则配置模块(通过数组对象的方式集中配置路由规则)
编写路由规则
react-router-config 用于辅助 React 路由,可以通过数组对象格式配置路由规则。
使用它提供的 renderRoutes 方法可以将数组对象格式的路由规则转换成<Switch>、<Route>组件去渲染。
// src\share\routes.js
import Home from './pages/Home'
import List from './pages/List'
const routes = [
{
path: '/',
component: Home,
exact: true // 精确匹配
},
{
path: '/list',
component: List,
exact: true // 精确匹配
}
]
export default routes
// renderRoutes(routes) 会被转换成:
/*
<Switch>
<Route path="/" exact>
<Home />
</Route>
<Route path="/list" exact>
<List />
</Route>
</Switch>
*/
实现服务器端路由
1 Express 路由接收任何请求
Express 路由接收所有 GET 请求,将请求信息传递给服务端渲染方法。
服务器端 React 路由通过请求路径匹配要进行渲染的组件。
// src/server/index.js
import app from './http'
import renderer from './renderer'
app.get('*', (req, res) => {
res.send(renderer(req))
})
2 服务器端路由配置
使用静态路由组件 <StaticRouter> 代替 <BrowserRouter>。
<StaticRouter> 用于服务器端渲染,它没有路由跳转功能,将客户端请求的地址传递给 location 属性,<StaticRouter> 渲染 location 匹配的组件。
// src\server\renderer.js
import React from 'react'
import {
renderToString } from 'react-dom/server'
import {
StaticRouter } from 'react-router-dom'
import {
renderRoutes } from 'react-router-config'
import routes from '../share/routes'
export default req => {
const content = renderToString(
<StaticRouter location={
req.path}>
{
renderRoutes(routes)}
</StaticRouter>
)
return `
<html>
<head>
<title>React SSR</title>
</head>
<body>
<div id="root">${
content}</div>
<script src="/bundle.js"></script>
</body>
</html>
`
}
关闭客户端二次渲染
现在由于客户端二次渲染(hydrate),访问 http://localhost:3000/list会被重新渲染为 / 路由内容。
有两个方式可以关闭客户端二次渲染:
- 取消加载二次渲染脚本
- 删掉
<script src="/bundle.js"></script>
- 删掉
- 浏览器禁止运行 JavaScript 脚本
- Chrome 为例,在设置中搜索
JavaScript,进入网站设置 - JavaScript
- Chrome 为例,在设置中搜索
实现客户端路由
客户端路由实现的方式和客户端渲染一样。
// src\client\index.js
import React from 'react'
import ReactDOM from 'react-dom'
import {
BrowserRouter } from 'react-router-dom'
import {
renderRoutes } from 'react-router-config'
import routes from '../share/routes'
ReactDOM.hydrate(
<BrowserRouter>
{
renderRoutes(routes)}
</BrowserRouter>,
document.getElementById('root')
)
添加一个链接测试客户端路由跳转是否成功:
// src\share\pages\Home.js
import React from 'react'
import {
Link } from 'react-router-dom'
function Home() {
return (
<div
onClick={
() => {
console.log('click')
}}
>
Home works
<Link to="/list"

本文介绍了一个React服务端渲染(SSR)项目的实现过程,包括客户端和服务端的路由与Redux支持,以及如何解决服务端渲染中遇到的数据获取问题。
最低0.47元/天 解锁文章
395

被折叠的 条评论
为什么被折叠?



