路由
路由
React 路由通常使用 react-router
库来实现,它是一个功能强大的库,用于在 React 应用程序中实现客户端路由。以下是关于如何在 React 中使用 React Router 的详细说明:
安装 React Router
npm install react-router-dom
主要API
- HashRouter与BrowserRouter,两个API是两种路由模式,被包裹,意味着当前组件开启了路由
- Link与NavLink,两个API用于路径跳转,最终会被渲染成【a】标签,可以通过【to】属性,设置路由跳转路径
- Route用于路径的匹配,被匹配到的路径,就会显示指定的页面
- path属性,用于设置路径匹配
- element属性,路径匹配成功后,要显示的组件。
- Switch用于匹配多个路由,只渲染第一个匹配的路由。
- useParams用于获取路径参数。
- useLocation用于获取当前路由的路径。
- useHistory用于获取路由的历史记录。
基本使用
创建基本组件
// Home.js
import React from 'react';
const Home = () => {
return <h2>Home</h2>;
};
export default Home;
//About.js
import React from 'react';
const About = () => {
return <h2>About</h2>;
};
export default About;
// Contact.js
import React from 'react';
import {
useNavigate
} from 'react-router-dom';
const Contact = () => {
const navigate = useNavigate()
return <div>
this is home
<button onClick={() => navigate('/')}>使用navigate跳去Home页面</button>
</div>;
};
export default Contact;
配置路由
import './App.css';
import Home from './Home';
import About from './About';
import Contact from './Contact';
import {
BrowserRouter as Router,
Routes,
Route,
Link,
} from 'react-router-dom';
function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</div>
</Router>
);
}
export default App;

- 路由的写法需要用
BrowserRouter
进行包裹,这其实就是history
模式的路由,哈西模式的路由是HashRouter
- 上面例子引入
Link
,这其实就是a
标签。react
中的路由入口是Routes
,里面去写单个的路由,单个路由需要写path
和element
- 上面例子使用
<button>
跳转到首页,使用useNavigate
这个 hooks 来跳转到首页,
当然,history
可以有回退的功能,就是可以缓存历史访问的页面,你想要关掉这个功能,只需要给 navigate
加入第二个参数: replace: true
<button onClick={() => navigate('/about' , { replace: true })}>跳去关于页面</button>
这样,你就无法回退了
路由传参
这里 react 有两种方式进行传参
1、Search传参
这种方式就是原生js
写法,直接 ?
拼接 url
后面传递
其他页面想要拿到这个参数需要引入一个 hooks
,useSearchParams
,这个方法的实例是一个数组,数组中用 get
拿到参数
import React from 'react';
import { BrowserRouter, Link, Routes, Route, useNavigate, useSearchParams } from 'react-router-dom'
const Home = () => {
const navigate = useNavigate()
return (
<div>
this is home
<button onClick={() => navigate('/about?id=123' , { replace: true })}>跳去关于页面</button>
</div>
)
}
const About = () => {
let [ params ] = useSearchParams()
console.log(params.get('id'));
return (
<div>this is about</div>
)
}
const 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;
你若用 Link
这样跳转页面,useSearchParams
是拿不到参数的,这种方法只能用 navigate
2、Params传参
这种方法你就可以传参不用 ?
,直接用 /
拼接即可,为了防止这个参数也是个路径,你需要在接收方引入一个 hooks
,useParams
,并且传参时需要在 Routes
中的路径中指明 path
有参数,并且用:写上参数名
import React from 'react';
import { BrowserRouter, Link, Routes, Route, useNavigate, useSearchParams, useParams } from 'react-router-dom'
const Home = () => {
const navigate = useNavigate()
return (
<div>
this is home
<button onClick={() => navigate('/about/123' , { replace: true })}>跳去关于页面</button>
</div>
)
}
const About = () => {
let params = useParams()
console.log(params.id);
return (
<div>this is about</div>
)
}
const App = () => {
return (
<div className='app'>
<BrowserRouter>
<Link to='/'>首页 | </Link>
<Link to='about'>关于</Link>
<Routes>
<Route path='/' element={<Home />}></Route>
<Route path='/about/:id' element={<About />}></Route>
</Routes>
</BrowserRouter>
</div>
);
};
export default App;
总结
提示
navigate('/about?id=123') 用 useSearchParams() 接受参数 navigate('/about/123') 用 useParams() 接受参数
嵌套路由(二级路由)
React Router 允许你创建嵌套路由,这样可以在一个组件内渲染更多的路由
App.js
import './App.css';
import Home from './home';
import About from './layout/about';
import Contact from './layout/contact';
import Layout from './layout';
import {
BrowserRouter as Router,
Routes,
Route,
} from 'react-router-dom';
function App() {
return (
<Router>
<div>
<Routes>
<Route path='/' element={<Home />}></Route>
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route path='about' element={<About />}></Route>
<Route path='contact' element={<Contact />}></Route>
</Route>
</Routes>
</div>
</Router>
);
}
export default App;
home.js
import React from 'react';
import {
useNavigate
} from 'react-router-dom';
const Home = () => {
const navigate = useNavigate()
return <div>
<h2>Home页面</h2>
<button onClick={() => navigate('/layout')}>跳转layout页面</button>
</div>;
};
export default Home;
layout.js
import React from 'react';
import { Link, Outlet } from 'react-router-dom'
const Layout = () => {
return (
<div>
<header style={{height: '80px', backgroundColor: '#eee'}}>header</header>
<section style={{display: 'flex'}}>
<aside style={{width: '200px', height: 'calc(100vh - 80px)', backgroundColor: 'yellow'}}>
<ul>
<li><Link to={'/layout/bbout'}>文章</Link></li>
<li><Link to={'/layout/contact'}>发布</Link></li>
</ul>
</aside>
<section>
<Outlet />
</section>
</section>
</div>
);
};
export default Layout;
这里的写法和 vue 有异曲同工之妙,二级路由无需打斜杠/
,同样的在 layout
中再写一个 Route
二级路由需要引入一个入口 Outlet
,Route
中的页面才会在这里面展示
layout/about.js
import React from 'react';
const About = () => {
return <h2>About页面</h2>;
};
export default About;
** layout/contact.js
**
import React from 'react';
import {
useNavigate
} from 'react-router-dom';
const Contact = () => {
const navigate = useNavigate()
return <div>
<h2>Contact 页面</h2>
<button onClick={() => navigate('/')}>跳去Home页面</button>
</div>;
};
export default Contact;

当然,我们也可以来到 layout
默认展示一个二级页面,实现方法有两种,这里以默认展示 About
页面为例
实现方法一:直接将 About 的 path 去掉,换成 index
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route index element={<About />}></Route>
<Route path='contact' element={<Contact />}></Route>
</Route>
这样做,About
的路径就是 layout
的路径
实现方法二: Navigate
{/* 二级路由 */}
<Route path='/layout' element={<Layout />}>
<Route path='' element={<Navigate to='/layout/about'/>}></Route>
<Route path="about" element={<About />}></Route>
<Route path='contact' element={<Contact />}></Route>
</Route>
写法上就是再写一个Route
,用作重定向
最后
react
的写法是一级路由入口直接 BrowserRouter
,而二级路由则需要写一个Outlet
才能展示