使用路由
在 React 服务端渲染(SSR)应用中使用路由,通常需要考虑如何在服务器端和客户端之间共享路由配置。一个流行的解决方案是使用 Next.js,它对 SSR 有很好的支持,并且内置了路由功能。然而,如果你想手动设置带有路由的 React SSR 应用,可以参考以下步骤:
1. 安装react-router-dom依赖
bash
yarn add react-router-dom@^5.0.0此外,为了处理静态文件和服务端渲染逻辑,你可能还需要安装webpack及相关加载器。
2. 添加页面
在src目录下创建一个名为pages的目录,并添加一些示例页面:
jsx
// src/pages/Home.jsx
const Home = () => {
return (
<div>
<h1>Home Page</h1>
<p>Welcome to the home page!</p>
<Link to="/about">Go to About</Link>
<Link to="/contact">Go to Contact</Link>
</div>
);
};
// src/pages/About.jsx
const About = () => {
return (
<div>
<h1>About Page</h1>
<p>Welcome to the about page!</p>
</div>
);
};
// src/pages/Contact.jsx
const Contact = () => {
return (
<div>
<h1>Contact Page</h1>
<p>Welcome to the contact page!</p>
</div>
);
};3. 配置路由
在 React 应用中,我们使用 react-router-dom 库来配置路由。
jsx
// src/routes/RouteApp.jsx
import React from "react";
import { Route, Switch } from "react-router-dom";
import Home from "@/pages/Home/index.jsx";
import About from "@/pages/About/index.jsx";
import Contact from "@/pages/Contact/index.jsx";
export default function RouteApp() {
return (
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route exact path="/contact" component={Contact} />
</Switch>
);
}4. 客户端引入路由
jsx
// client/App.jsx
import React from "react";
import "@/assets/global.css";
import RouteApp from "@/routes/routeApp";
import { BrowserRouter } from "react-router-dom";
export default () => {
return (
<BrowserRouter>
<RouteApp />
</BrowserRouter>
);
};5. 服务端引入路由
jsx
// server/App.jsx
import React from "react";
import "@/assets/global.css";
import RouteApp from "@/routes/routeApp";
import { StaticRouter } from "react-router-dom";
export default ({ location, context }) => {
return (
<StaticRouter location={location} context={context}>
<RouteApp />
</StaticRouter>
);
};- StaticRouter:用于服务端渲染的组件,它接收两个参数:location 和 context。location 是当前请求的路径,context 是一个对象,用于传递路由信息。
6. 服务端入口文件传递路由信息
jsx
export default (req, res) => {
const context = {};
const componentHTML = ReactDom.renderToString(
<App location={req.path} context={context} />
);
res.send(getHtmlTemplate(componentHTML));
};- location:
req.path是请求路径,StaticRouter会根据这个路径来渲染页面。 - context:
StaticRouter会根据这个对象来判断是否跳转路由。
7. 通过配置方式生成路由
route.config.js
jsx
import Home from "@/pages/Home/index.jsx";
import About from "@/pages/About/index.jsx";
import Contact from "@/pages/Contact/index.jsx";
export const routes = [
{
key: "home",
path: "/",
component: Home,
},
{
key: "about",
path: "/about",
component: About,
},
{
key: "contact",
path: "/contact",
component: Contact,
},
];RouteApp.jsx
jsx
import React from "react";
import { Route, Switch } from "react-router-dom";
import routes from "./route.config.js";
export default function RouteApp() {
return (
<Switch>
{routes.map((route) => (
<Route {...route} />
))}
</Switch>
);
}使用第三方库
bash
yarn add react-router-configjsx
// src/routes/RouteApp.jsx
import React from "react";
import { Route, Switch } from "react-router-dom";
import routes from "./route.config.js";
import { renderRoutes } from "react-router-config";
export default function RouteApp() {
return <>{renderRoutes(routes)}</>;
}注意事项
- Context:在上述例子中,
context对象用于处理重定向。如果StaticRouter中的context.url被设置了值,这意味着发生了重定向。 - Webpack 配置:确保你的 Webpack 配置能够正确地为客户端和服务端生成 bundle。对于服务端渲染,你可能需要两个不同的 entry points 或使用插件如
webpack-node-externals来排除 node_modules。
通过以上步骤,你应该能够在 React SSR 应用中成功实现路由功能。不过,请注意手动设置这样的环境可能会比较复杂,尤其是涉及到错误处理、性能优化等方面。