react router v6的基本使用_艾贝尔白音的博客-爱代码爱编程
Router v6的基本使用
前言
路由干啥的就先不介绍了
Router的基本使用
安装路由
npm install react-router-dom
npm install @types/react-router-dom
配置路由
在入口文件导入 BrowserRouter
或 HashRouter
组件
// index.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals()
基本用法
// app.tsx
import React from 'react'
import { Link, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
return (
<div>
<Link to='/'>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/' element={<Home />} />
</Routes>
</div>
)
}
export default App;
Router的用法详解
默认路由 index
// app.tsx
import React from 'react'
import { Link, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
return (
<div>
<Link to='/home'>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} />
<Route index element={<Home />} />
</Routes>
</div>
)
}
export default App;
上面这个例子中,如果使用index
指定默认路由为Home
组件,我们打开网页时,就会默认显示Home
组件。
如果我们不使用index
指定默认路由,假如当前网页地址为http://127.0.0.1:3000
,Home
组件需要匹配 url 为http://127.0.0.1:3000/home
,而About
组件需要匹配 url 为http://127.0.0.1:3000/about
,而当前 url 为http://127.0.0.1:3000
,匹配不了,所以Home
组件和About
组件都不会直接显示在页面上,需要我们点击对应的 Link 才会显示对应的组件。
路由重定向 Navigate
// app.tsx
import React from 'react'
import { Link, Navigate, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
return (
<div>
<Link to='/home'>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} />
<Route path='/' element={<Navigate to='/home' />} />
</Routes>
</div>
)
}
export default App;
上面这个例子中,Navigate
会将http://127.0.0.1:3000/
重定向为http://127.0.0.1:3000/home
,所以打开网页就会显示Home
组件
注意在上面的两个案例中,使用index和Navigate都网页打开就默认显示了Home组件,但是其中还是有一些区别的:
- 使用
index
,打开网页时,url还是为http://127.0.0.1:3000
- 使用和
Navigate
,打开网页时url
会自动跳转到http://127.0.0.1:3000/home
选中样式 NavLink
我们希望点击HOME跳转到Home
组件,点击ABOUT跳转到About
组件,但同时还希望显示Home
组件时,HOME能有一个样式(比如HOME这几个字的背景变为红色),显示About
组件时,ABOUT能有一个样式,这个时候就需用用到NavLink了
// app.tsx
import React from 'react'
import { Navigate, NavLink, Route, Routes } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
import './App.css'
function App() {
return (
<div>
<NavLink to='/home' className={({ isActive }) => isActive ? "selected" : ""}>HOME</NavLink>
<NavLink to='/about' className={({ isActive }) => isActive ? "selected" : ""}>ABOUT</NavLink>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} />
<Route path='/' element={<Navigate to='/home' />} />
</Routes>
</div>
)
}
export default App;
/* App.css */
.selected {
background-color: red;
}
在({ isActive }) => isActive ? "selected" : ""
中,:
前面前面写选中的样式,:
后面写未选择的样式。
编程式路由导航 useNavigate
前面所讲的路由跳转方式(Link
,NavLink
)都是声明式路由导航,现在我们有这么一个需求,点击某个按按钮(<button></button>
)跳转到特定页面,就需要用到编程式路由导航useNavigate
// app.tsx
import React from 'react'
import { Route, Routes, useNavigate } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
const navigate = useNavigate();
function goToHome() {
navigate('/home');
}
function goToAbout() {
navigate('/about');
}
return (
<div>
<button onClick={goToHome}>Home</button>
<button onClick={goToAbout}>About</button>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} />
</Routes>
</div>
)
}
export default App;
路由嵌套 Outlet
假如路由组件Home
,下面还有两个路由组件FristHome
和SecondHome
,这个时候就需要用到路由嵌套
// app.tsx
// app.tsx
import React from 'react'
import { Link, Route, Routes, } from 'react-router-dom'
import About from './pages/About'
import FristHome from './pages/FirstHome'
import Home from './pages/Home'
import SecondHome from './pages/SecondHome'
function App() {
return (
<div>
<Link to='/home'>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} >
<Route path='first' element={<FirstHome />} />
<Route path='second' element={<SecondHome />} />
</Route>
</Routes>
</div>
)
}
export default App;
Outlet
组件主要起到一个占位用作用,用于标记子路由显示的位置。
// pages/Home.tsx
import React from 'react'
import { Link, Outlet } from 'react-router-dom'
function Home() {
return (
<div>
<h1>Home 组件</h1>
<Outlet />
<Link to='first'>FristHome</Link>
<Link to='second'>SecondHome </Link>
</div>
)
}
export default Home
路由表 useRoutes
普通使用
// router/routerCfg
import About from "../pages/About";
import Home from "../pages/Home";
const routerCfg = [
{
path: '/home',
element: <Home />,
},
{
path: '/about',
element: <About />
},
]
export default routerCfg;
// app.tsx
import React from 'react'
import { Link, Route, Routes, useRoutes, } from 'react-router-dom'
import routerCfg from './router/routerCfg';
function App() {
return (
<div>
<Link to='/home'>Home</Link>
<Link to='/about'>About </Link>
{useRoutes(routerCfg)}
</div>
)
}
export default App;
重定向
// router/routerCfg
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import Home from "../pages/Home";
const routerCfg = [
{
path: '/home',
element: <Home />,
},
{
path: '/about',
element: <About />
},
{
path: '/',
element: <Navigate to='/home' />
}
]
export default routerCfg;
路由嵌套
// router/routerCfg
import { Navigate } from "react-router-dom";
import About from "../pages/About";
import FristHome from "../pages/FirstHome";
import Home from "../pages/Home";
import SecondHome from "../pages/SecondHome";
const routerCfg = [
{
path: '/home',
element: <Home />,
children: [
{
path: 'first',
element: <FristHome />
},
{
path: 'second',
element: <SecondHome />
}
]
},
{
path: '/about',
element: <About />
},
{
path: '/',
element: <Navigate to='/home' />
}
]
export default routerCfg;
路由懒加载
// router/routerCfg
import React from "react";
import { Navigate } from "react-router-dom";
const About = React.lazy(() => import('../pages/About'));
const FristHome = React.lazy(() => import('../pages/FirstHome'));
const Home = React.lazy(() => import('../pages/Home'));
const SecondHome = React.lazy(() => import('../pages/SecondHome'));
const routerCfg = [
{
path: '/home',
element: <Home />,
children: [
{
path: 'first',
element: <FristHome />
},
{
path: 'second',
element: <SecondHome />
}
]
},
{
path: '/about',
element: <About />
},
{
path: '/',
element: <Navigate to='/home' />
}
]
export default routerCfg;
// app.tsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routerCfg from './router/routerCfg';
function App() {
return (
<div>
<Link to='/home'>Home</Link>
<Link to='/about'>About </Link>
<Suspense fallback={<div>Loading...</div>}>
{useRoutes(routerCfg)}
</Suspense>
</div>
)
}
export default App;
路由传递参数
params参数 useParams
// app.tsx
import React from 'react'
import { Link, Route, Routes, } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
const id = '233';
const name = 'baiyin';
return (
<div>
<Link to={`/home/${id}/${name}`}>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/home/:id/:name' element={<Home />} />
<Route path='/about' element={<About />} />
</Routes>
</div>
)
}
export default App;
// pages/Home.tsx
import React from 'react'
import { useParams } from 'react-router-dom'
function Home() {
//获取params参数的消息
const { id, name } = useParams();
return (
<div>
<h1>Home 组件</h1>
<h2>{id}---{name}</h2>
</div>
)
}
export default Home
search参数 useSearchParams
// app.tsx
import React from 'react'
import { Link, Route, Routes, } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
const id = '233';
const name = 'baiyin';
return (
<div>
<Link to={`/home?id=${id}&name=${name}`}>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/home' element={<Home />} />
<Route path='/about' element={<About />} />
</Routes>
</div>
)
}
export default App;
// pages/Home.tsx
import React from 'react'
import { useSearchParams } from 'react-router-dom'
function Home() {
// 接收serach参数
const [search, setSearch] = useSearchParams();
const id = search.get("id");
const name = search.get("name");
return (
<div>
<h1>Home 组件</h1>
<h2>{id}---{name}</h2>
</div>
)
}
export default Home
state参数 useLocation
// app.tsx
import React from 'react'
import { Link, Route, Routes, } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
const id = '233';
const name = 'baiyin';
return (
<div>
<Link to={`/home`} state={{ id: id, name: name }}>Home</Link>
<Link to='/about'>About </Link>
<Routes>
<Route path='/home' element={<Home />} />
<Route path='/about' element={<About />} />
</Routes>
</div>
)
}
export default App;
// pages/Home.tsx
import React from 'react'
import { useLocation, useSearchParams } from 'react-router-dom'
function Home() {
// 接收state参数
const { state: { id, name } } = useLocation();
return (
<div>
<h1>Home 组件</h1>
<h2>{id}---{name}</h2>
</div>
)
}
export default Home
使用useNavigate
传递state参数,接收还是用useLocation
。
// app.tsx
import React from 'react'
import { Route, Routes, useNavigate } from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home'
function App() {
const navigate = useNavigate();
const id = '233';
const name = 'baiyin';
function goToHome() {
navigate('/home', {
replace: false,
state: {
id: id,
name: name,
}
});
}
function goToAbout() {
navigate('/about');
}
return (
<div>
<button onClick={goToHome}>Home</button>
<button onClick={goToAbout}>About</button>
<Routes>
<Route path='/about' element={<About />} />
<Route path='/home' element={<Home />} />
</Routes>
</div>
)
}
export default App;
注意:state参数最好不要用来的传递react state里的需要频繁变动,且需要路由组件做出相应的反馈的数据,state参数需要点击链接,才能向下传递数据。
而传递参数使用路由表的话,把Routes
里面的转写成路由表就行了。
注意点
-
默认情况下就是精确匹配(匹配完整路径),如果像匹配某某一部分,在路径后面加
/*
-
Route能够自动找出最优的匹配路径,Route先后顺序不重要