文档信息
快速开始
API 风格路由(推荐)
jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import {
RouterProvider,
createHashRouter,
Link,
Outlet,
} from "react-router-dom";
// --- components
const App = () => {
return (
<div>
<div className="nav-links">
<Link to="/">home</Link>
<span> | </span>
<Link to="/about">about</Link>
</div>
<div className="main-conetnt">
{/* <!-- useOutlet() --> */}
<Outlet />
</div>
</div>
);
};
const Home = () => <div>home page</div>;
const About = () => <div>about</div>;
// --- router
const router = createHashRouter([
{
path: "/",
element: <App />,
children: [
{
index: true,
element: <Home />,
},
{
path: "/about",
element: <About />,
},
],
},
]);
// --- render
createRoot(document.querySelector("#app")).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>
);
组件风格路由
jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { HashRouter as Router, Link, Routes, Route } from "react-router-dom";
// --- components
const Home = () => <div>home page</div>;
const About = () => <div>about</div>;
const App = () => {
return (
<div>
<div className="nav-links">
<Link to="/">home</Link>
<span> | </span>
<Link to="/about">about</Link>
</div>
<div className="main-conetnt">
<Routes>
<Route path="/" element={<Home />} index={true} />
<Route path="/about" element={<About />} />
</Routes>
</div>
</div>
);
};
// --- render
createRoot(document.querySelector("#app")).render(
<StrictMode>
<Router>
<App />
</Router>
</StrictMode>
);
API & Components & hooks
API
Router Components
Components
- Link 类似于 a 标签的功能但是做了其他额外处理
- NavLink 功能非常类似 link,不同是可以检测当前 location 路径是否是组件绑定的 path
- Navigate 当组件渲染的时候自动跳到指定路径
- Outlet 类似 vue-router 的 router-view 的效果, 视图的出口
- Routes(like Switch) 类似 react-router 5.x 中的 switch 组件的功能
- Route & Route 属性选项 用于指定路径对应的组件
<Route element={<div>hello</div>} />
, 和 react-router 5.x 的 Route 功能是一样的
hooks
- useLoaction 获取 location 对象
- useOutlet 获取渲染的组件
- useParams 获取参数
- useSearchParams 获取 url 的
query
并解析为对象 - useRoutes 渲染路由表
动态路由
jsx
// router 定义参数路径
const router = createHashRouter([
{
path: "/about/:aboutId",
element: <About />,
},
]);
// 使用时: 拼接 path 路径
const aboutLink = (
<Link to={"/about/" + Math.ceil(Math.random() * 10)}>about</Link>
);
// 获取参数, 如果是 ?a=b 可以用 useSearchParams()
const About = () => {
const { aboutId } = useParams();
return <div>hello: {aboutId}</div>;
};
编程式导航(手动跳转)
jsx
const Home = () => {
const navigate = useNavigate(); // return a function to switch routes
return (
<div>
<div> home page </div>
<div>
<button onClick={() => navigate("/about/3")}>click</button>
</div>
</div>
);
};
中间件
这个插件比较轻量级, 代码很少也很好理解, 有不符合需求的地方, 可以直接自己修改
jsx
import { StrictMode, useEffect } from "react";
import { createRoot } from "react-dom/client";
import { useRoutesWithMiddleware } from "react-router-middleware-plus";
import {
HashRouter as Router,
Link,
useOutlet,
useNavigate,
} from "react-router-dom";
// --- components
const App = () => {
return (
<div>
<div className="nav-links">
<Link to="/">home</Link>
<span> | </span>
<Link to="/about">about</Link>
</div>
<div className="main-conetnt">{useOutlet()}</div>
</div>
);
};
const Home = () => (
<div>
home page
<div>
<button onClick={() => window.localStorage.setItem("isLogin", true)}>
模拟登录
</button>
</div>
<div>
<button onClick={() => window.localStorage.setItem("isLogin", "")}>
退出登录
</button>
</div>
</div>
);
const About = () => <div>about</div>;
// --- middleware
function checkLogin({ children }) {
const isLogin = localStorage.getItem("isLogin");
const navigate = useNavigate();
useEffect(() => {
if (!isLogin) {
alert("请先登录");
navigate("/");
}
}, [isLogin]);
return isLogin ? children : null;
}
// --- router component like: useRoutes(routes)
function AppRouter() {
const routes = [
{
path: "/",
element: <App />,
children: [
{
index: true,
element: <Home />,
},
{
path: "/about",
element: <About />,
middleware: [checkLogin], // 匹配到这时: 先执行中间件(验证登录)
},
],
},
];
return useRoutesWithMiddleware(routes);
}
// --- render
createRoot(document.querySelector("#app")).render(
<StrictMode>
<Router>
<AppRouter />
</Router>
</StrictMode>
);