Skip to content

使用路由

在 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));
};
  • locationreq.path是请求路径,StaticRouter会根据这个路径来渲染页面。
  • contextStaticRouter会根据这个对象来判断是否跳转路由。

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-config
jsx
// 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 应用中成功实现路由功能。不过,请注意手动设置这样的环境可能会比较复杂,尤其是涉及到错误处理、性能优化等方面。

Released under the MIT License.