创建路由开发环境
1 2
| # 安装最新的ReactRouter包 npm i react-router-dom
|
简单的路由实例
在 index.js
中,实现一个简单的路由实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import store from './store' import { Provider } from 'react-redux';
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
const router = createBrowserRouter([ { path: '/', element: <App></App> }, { path: '/login', element: <div>我是登录页</div> }, { path: '/article', element: <div>我是文章页</div> } ]) const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> {/* 在组件中使用RouterProvider实现路由 */} <RouterProvider router={router}></RouterProvider> </Provider> );
|
抽象路由模块
page/模块:
1 2 3 4 5
| const Login = () => { return <div>我是登录页</div> } export default Login
|
router模块:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import App from '../App'; import Login from "../page/login"; import Article from "../page/article"; import { createBrowserRouter } from "react-router-dom"; const router = createBrowserRouter([ { path: '/', element: <App></App> }, { path: '/login', element: <Login></Login> }, { path: '/article', element: <Article></Article> } ]) export default router
|
应用入口文件渲染 RouterProvider:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React from 'react'; import ReactDOM from 'react-dom/client'; import store from './store' import { Provider } from 'react-redux';
import { RouterProvider } from 'react-router-dom'; import router from './router'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <Provider store={store}> // 注入router <RouterProvider router={router}></RouterProvider> </Provider> );
|
路由导航
声明式导航
声明式导航是指通过在模版中通过 <Link/>
组件描述出要跳转到哪里去
1 2 3 4 5 6 7 8 9
| import { Link } from "react-router-dom" const Login = () => { return ( <div>我是登录页<Link to="/">主页</Link></div> ) } export default Login
|
通过给组件的to属性指定要跳转到路由path,组件会被渲染为浏览器支持的a链接,如果需要传参直接通过字符串拼接的方式拼接参数即可
编程式导航
编程式导航是指通过 useNavigate
钩子得到导航方法,然后通过调用方法以命令式的形式进行路由跳转
1 2 3 4 5 6 7 8 9 10 11 12
| import { useNavigate } from "react-router-dom" const Login = () => { const navigate = useNavigate() return ( <div>我是登录页 <button onClick={() => navigate('/article')}>文章</button> </div> ) } export default Login
|
通过调用 navigate方法 传入地址 path 实现跳转
导航传参
searchParams 传参
1 2
| <button onClick={() => navigate('/article?id=666&name=Alien')}>文章(传参)</button>
|
1 2 3
| const [params] = useSearchParams() <div>{params.get('id')}{params.get('name')}</div>
|
params 传参
1 2 3 4 5
| { path: '/login/:id', element: <Login></Login> },
|
1 2
| <button onClick={() => navigate('/login/1001')}>登录(传参)</button>
|
1 2 3
| const params = useParams() <div>{params.id}</div>
|
嵌套路由配置
实现步骤:
- 使用
children
属性配置路由嵌套关系
- 使用
<Outlet/>
组件配置二级路由渲染位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { path: '/', element: <Layout />, children: [ { path: 'about', element: <About />, }, { path: 'board', element: <Board />, } ] }
|
1 2 3 4 5 6 7 8 9 10
| const Layout = () => { return ( <div> <Link to="/about">关于</Link> <Link to="/board">面板</Link> {/* 二级路由出口 */} <Outlet /> </div> ) }
|
默认二级路由
当访问的是一级路由时,默认的二级路由组件可以得到渲染,只需要在二级路由的位置去掉path,设置index属性为true
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { path: '/', element: <Layout />, children: [ { index: true, element: <About />, }, { path: 'board', element: <Board />, } ] }
|
404路由配置
场景:当浏览器输入url的路径在整个路由配置中都找不到对应的 path,为了用户体验,可以使用 404 兜底组件进行渲染
实现步骤:
- 准备一个 NotFound组件
- 在路由表数组的末尾,以
*
号作为路由path配置路由
1 2 3 4 5 6
| const NotFound = () => { return <div>404找不到目标</div> } export default NotFound
|
1 2 3 4 5
| { path: '*', element: <NotFound></NotFound> }
|
两种路由模式
各个主流框架的路由常用的路由模式有俩种,history模式 和 hash模式,ReactRouter 分别由 createBrowerRouter 和 createHashRouter 函数负责创建
路由模式 |
url表现 |
底层原理 |
是否需要后端支持 |
history |
url/login |
history对象 + pushState事件 |
需要 |
hash |
url/#/login |
监听hashChange事件 |
不需要 |