概述
一个路径path
对应一个组件component
当我们在浏览器中访问一个path
的时候,path
对应的组件会在页面中进行渲染。
使用
快速开始
安装依赖
npm i react-router-dom
基本使用
import { createBrowserRouter, RouterProvider } from 'react-router-dom'
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: '/login',
element: <div>登录页面</div>
},
{
path: '/article',
element: <div>文章页面</div>
}
]);
createRoot(document.getElementById('root')).render(
<StrictMode>
<RouterProvider router={router} />
</Provider>
</StrictMode>,
)
路由抽离
- 在
src
目录下创建pages
文件夹用来存放页面组件 - 在
src
目录下创建router
文件夹用来存放路由 main.ts
注入router
实例
router.jsx
必须是.jsx
不是.js
,.js
里识别不了组件元素
import { createBrowserRouter } from "react-router-dom";
import App from "../App.jsx";
import Login from "../pages/login.jsx";
import Article from "../pages/article.jsx";
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: "/login",
element: <Login />,
},
{
path: "/article",
element: <Article />,
},
]);
export default router;
main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import store from './store'
import { Provider } from 'react-redux'
import { RouterProvider } from 'react-router-dom'
import router from './router/index'
createRoot(document.getElementById('root')).render(
<StrictMode>
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
</StrictMode>,
)
路由导航
路由系统中的多个路由之间需要进行路由跳转,并且在跳转的同时有可能需要传递参数进行通信
声明式导航
声明式导航是指在模板中通过<Link />
组件描述出要跳转到哪里去。通过给组件的to
属性指定要跳转到的路由path
,组件会被渲染为浏览器支持的a
链接,如果需要传参直接通过字符串拼接的方式拼接参数
import {Link} from "react-router-dom"
const Login = () => {
return (
<div>
我是登录页面
<Link to="/">返回首页</Link>
</div>
)
}
export default Login
编程式导航
编程式导航是指通过useNavigate
钩子得到导航方法,然后通过调用方法以命令式的形式进行路由跳转,这种方式更加灵活
import { useNavigate } from "react-router-dom"
const Login = () => {
const navigate = useNavigate()
return (
<div>
我是登录页面
<button onClick={() => { navigate('/') }}>返回首页</button>
</div>
)
}
export default Login
路由传参
searchParams传参
import { useNavigate } from "react-router-dom"
const Login = () => {
const navigate = useNavigate()
return (
<div>
我是登录页面
<button onClick={() => { navigate('/article?id=123&name=tom') }}>打开文章</button>
</div>
)
}
export default Login
import { useSearchParams } from "react-router-dom"
const Article = () => {
const [searchParams] = useSearchParams()
const id = searchParams.get('id')
return (
<div>
我是文章页面,id是:{id}
</div>
)
}
export default Article
params传参
import { useNavigate } from "react-router-dom"
const Login = () => {
const navigate = useNavigate()
return (
<div>
我是登录页面
<button onClick={() => { navigate('/article/123/tom') }}>打开文章</button>
</div>
)
}
export default Login
import { useParams } from "react-router-dom"
const Article = () => {
const params = useParams()
const id = params.id
const name = params.name
return (
<div>
我是文章页面,id是:{id},name是:{name}
</div>
)
}
export default Article
const router = createBrowserRouter([
{
path: "/",
element: <App />,
},
{
path: "/login",
element: <Login />,
},
{
path: "/article/:id/:name",
element: <Article />,
},
]);
这种方式必须要在路由中添加相应的占位符才可以进行匹配
嵌套路由
- 使用
children
属性配置路由嵌套关系 - 使用
<Outlet />
组件配置二级路由渲染位置
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
path: '/about',
element: <About />
}
]
},
{
path: "/login",
element: <Login />,
},
{
path: "/article/:id/:name",
element: <Article />,
},
]);
import { Outlet, Link } from 'react-router-dom'
import './App.css'
function App() {
return (
<div>
主页
<Link to="/about">关于</Link>
{/* 二级路由出口 */}
<Outlet />
</div>
);
}
export default App
默认二级路由配置
当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path
,设置index
属性为true
const router = createBrowserRouter([
{
path: "/",
element: <App />,
children: [
{
index: true,
element: <About />
}
]
},
{
path: "/login",
element: <Login />,
},
{
path: "/article/:id/:name",
element: <Article />,
},
]);
404 路由
当浏览器输入url
的路径在整个路由配置中都找不到对应的path
,为了用户体验,可以使用404
兜底组件进行渲染
const router = createBrowserRouter([
{
path: "*",
element: <NotFound />
}
]);