概述
一个路径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.idconst name = params.namereturn (<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 />}
]);