# react-router react路由 v6版本
- BrowserRouter
- Routes
- Route
- Link
- Outlet
cnpm i react-router-dom --save
# React-router
React-router 提供了一些 router 的核心 api,包括 Router, Route, Switch等,但是它没有提供 dom 操作进行跳转的 api , 服务器端渲染很适合。
# react-router-dom
React-router-dom 提供了BrowserRouter,HashRouter,Link 等等在 web 端常用的 DOM 类组件,可以通过 dom 的事件控制路由。例如点击一个按钮进行跳转,它也是基于react-router扩充,所以web开发可以只引入react-router-dom即可。
# router使用案例
- 创建router/index.js
- HashRouter:表示一个路由的跟容器,将来所有跟路由相关的东西,都要包裹在HashRouter中,一个网站中,只需要使用一次HashRouter就好了
- BrowserRouter:注意后台需要做处理
- 在v6版本中,使用 Route 需要在 Routes 标签包裹下 ,v5版本则不需要
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from '../pages/Home';
import OutletDemo from '../pages/OutletDemo';
import Page1 from '../pages/Page1';
import Page2 from '../pages/Page2';
function router () {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/outlet" element={<OutletDemo />}>
<Route path="/outlet/page1" element={<Page1 />}/>
<Route path="/outlet/page2" element={<Page2 />}/>
</Route>
</Routes>
</Router>
)
}
export default router;
- 在App.js中引入编写好的router
import Router from './router/index.js'
function App () {
return (
<div>
<Router></Router>
</div>
)
}
export default App;
- 创建pages文件夹,创建Home OutletDemo Page1 Page2文件
- Link:相当于a标签
- Outlet:为特定路由呈现任何匹配的子元素,嵌套子路由使用
//Home.js
import { Link } from 'react-router-dom';
function Home () {
return (
<div>
<Link to="/outlet">跳转到OutletDemo页面</Link>
</div>
)
}
export default Home;
//OutletDemo.js
import { Link, Outlet } from 'react-router-dom'
function OutletDemo () {
return (
<div>
<h1>我是Outlet页面</h1>
<Link to="/outlet/page1">跳转到Page1</Link>
<Link to="/outlet/page2">跳转到Page2</Link>
<Outlet></Outlet>
</div>
)
}
export default OutletDemo;
//Page1.js Page2.js改下名字就可以了
function Page1 () {
return (
<div>
<h1>Page1页面</h1>
</div>
)
}
export default Page1;
// 引入必要的内置组件
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
// 准备俩个路由组件
const Home = () => <div>this is home</div>
const About = () => <div>this is about</div>
function App() {
return (
<div className="App">
{/* 按照规则配置路由 */}
<BrowserRouter>
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
</Routes>
</BrowserRouter>
</div>
)
}
export default App
# react-router v6 核心内置组件说明
- BrowerRouter
作用: 包裹整个应用,一个React应用只需要使用一次
| 模式 | 实现方式 | 路由url表现 |
|---|---|---|
| HashRouter | 监听url hash值实现 | http://localhost:3000/#/about |
| BrowerRouter | h5的 history.pushState API实现 | http://localhost:3000/about |
- Link
作用: 用于指定导航链接,完成声明式的路由跳转 类似于 <router-link/>
<Link to="/">首页</Link>
这里to属性用于指定路由地址,表示要跳转到哪里去,Link组件最终会被渲染为原生的a链接
- Routes
作用: 提供一个路由出口,组件内部会存在多个内置的Route组件,满足条件的路由会被渲染到组件内部,类比 router-view
<Routes>
{/*满足条件的组件会被渲染到这儿*/}
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<About />}></Route>
</Routes>
- Route
作用: 用于定义路由路径和渲染组件的对应关系 [element:因为react体系内 把组件叫做react element]
<Route path="/about" element={<About />}></Route>
其中path属性用来指定匹配的路径地址,element属性指定要渲染的组件,图中配置的意思为: 当url上访问的地址为 /about 时,当前路由发生匹配,对应的About组件渲染
# react 编程式导航
概念: 通过js编程的方式进行路由页面跳转,比如说从首页跳转到关于页
- 实现步骤:
- 导入一个 useNavigate 钩子函数
- 执行 useNavigate 函数 得到 跳转函数
- 在事件中执行跳转函数完成路由跳转
// 导入useNavigate函数
import { useNavigate } from 'react-router-dom'
const Home = () => {
// 执行函数
const navigate = useNavigate()
return (
<div>
Home
<button onClick={ ()=> navigate('/about') }> 跳转关于页 </button>
</div>
)
}
export default Home
注: 如果在跳转时不想添加历史记录,可以添加额外参数replace 为true
navigate('/about', { replace: true } )
# 路由传参
- searchParams传参
- useSearchParams()
// Home
// 导入useNavigate函数
import { useNavigate } from 'react-router-dom'
const Home = () => {
// 执行函数
const navigate = useNavigate()
return (
<div>
Home
<button onClick={ ()=> navigate('/about?id=100',{replace:true}) }> 跳转关于页 </button>
</div>
)
}
export default Home
//About组件
// 导入useNavigate函数
import { useSearchParams } from 'react-router-dom'
const Home = () => {
// 执行函数
const [params] = useSearchParams()
console.log(params)
return (
<div>
about{params.get('id')}
</div>
)
}
export default Home
- params传参
<!-- Home修改 -->
<button onClick={ ()=> navigate('/about/1000',{replace:true}) }> 跳转关于页 </button>
// 导入useNavigate函数
import { useParams} from 'react-router-dom'
const Home = () => {
// 执行函数
const params = useParams()
console.log(params)
return (
<div>
about--{params.id}
</div>
)
}
export default Home
<Route path="/about/:id" element={<About />}></Route>
注意
- const params = useParams()
- const [params] = useSearchParams()
- 注意二者写法的不同
# react嵌套路由
# 实现步骤:
- App.js中定义嵌套路由声明
- Layout组件内部通过
<Outlet/>指定二级路由出口
- App.jsx
<Routes>
<Route path="/" element={<Layout/>}>
<Route path="board" element={ <Board/> } />
<Route path="article" element={ <Article/> } />
</Route>
{ /* 省略部分 */ }
</Routes>
- Layout.jsx
import { Outlet } from 'react-router-dom'
const Layout = () => {
return (
<div>
layout
{ /* 二级路由的path等于 一级path + 二级path */ }
<Link to="/board">board</Link>
<Link to="/article">article</Link>
{ /* 二级路由出口 */ }
<Outlet/>
</div>
)
}
export default Layout
# 默认二级路由和404
# 实现步骤:
- 给默认二级路由标记index属性
- 把原本的路径path属性去掉
<Routes>
<Route path="/" element={<Layout/>}>
<Route index element={ <Board/> } />
<Route path="article" element={ <Article/> } />
</Route>
</Routes>
import { Outlet } from 'react-router-dom'
const Layout = () => {
return (
<div>
layout
{ /* 默认二级不再具有自己的路径 */ }
<Link to="/">board</Link>
<Link to="/article">article</Link>
{ /* 二级路由出口 */ }
<Outlet/>
</div>
)
}
- 404配置
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Board />} />
<Route path="article" element={<Article />} />
</Route>
<Route path="*" element={<NotFound />}></Route>
</Routes>
</BrowserRouter>
# react集中式路由配置
场景: 当需要路由权限控制时候, 对路由数组做一些权限的筛选过滤,所谓的集中式路由配置就是用一个数组统一把所有的路由对应关系写好替换 本来的Roues组件
import { BrowserRouter, Routes, Route, useRoutes } from 'react-router-dom'
import Layout from './pages/Layout'
import Board from './pages/Board'
import Article from './pages/Article'
import NotFound from './pages/NotFound'
// 1. 准备一个路由数组 数组中定义所有的路由对应关系
const routesList = [
{
path: '/',
element: <Layout />,
children: [
{
element: <Board />,
index: true, // index设置为true 变成默认的二级路由
},
{
path: 'article',
element: <Article />,
},
],
},
// 增加n个路由对应关系
{
path: '*',
element: <NotFound />,
},
]
// 2. 使用useRoutes方法传入routesList生成Routes组件
function WrapperRoutes() {
let element = useRoutes(routesList)
return element
}
function App() {
return (
<div className="App">
<BrowserRouter>
{/* 3. 替换之前的Routes组件 */}
<WrapperRoutes />
</BrowserRouter>
</div>
)
}
export default App
← 高阶组件 react组件的声明方式 →