简介
React Router 是一款适用于 React 的多策略路由管理库。
文档
react router V6文档:
安装
css
npm install react-router-dom@6
声明式导航
初始化路由
从 react-router-dom 中导出 BrowserRouter ,使用 BrowserRouter 包裹App组件
javascript
// index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
// 引入路由模块
import { BrowserRouter } from 'react-router-dom';
import App from './App';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
//<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
//</React.StrictMode>
);
配置路由
修改 App.tsx ,添加路由配置
javascript
import React, { useEffect, useRef, useState } from 'react';
import { Link, Route, Routes } from 'react-router-dom';
const Home = () => {
return (
<div>
<nav>
<Link to="/about">About</Link>
</nav>
<main>
<h2>Home</h2>
</main>
</div>
)
}
const About = () => {
return (
<div>
<nav>
<Link to="/">Home</Link>
</nav>
<main>
<h2>About</h2>
</main>
</div>
)
}
function App() {
return (
<div className="App">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</div>
);
}
export default App;
添加链接
使用 Link 添加链接,可以更改URL而不会导致页面重新加载,与 Route 配合可以实现路由跳转
javascript
import React, { useEffect, useRef, useState } from 'react';
import { Link, Route, Routes } from 'react-router-dom';
function App() {
return (
<div className="App">
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</div>
);
}
export default App;
嵌套路由
Route 之间可以进行嵌套,父路内容在子组件之间进行共享,通过 Outlet 承接子组件内容。
javascript
// Home/index.tsx
const Home = () => {
return (
<div>
<h2>Home</h2>
</div>
)
}
export default Home;
// About/index.tsx
const About = () => {
return (
<div>
<h2>About</h2>
</div>
)
}
export default About;
javascript
// App.tsx
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, Outlet } from 'react-router-dom';
function App() {
return (
<div className="App">
<nav>
<h2>App</h2>
<Link to="/home">Home</Link> |
<Link to="/about">About</Link>
</nav>
{/* 承接子路由内容 */}
<Outlet />
</div>
);
}
export default App;
javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import App from './App';
import Home from './pages/Home';
import About from './pages/About';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="home" element={<Home />} />
<Route path="about" element={<About />} />
</Route>
</Routes>
</BrowserRouter>
);
无匹配路由
当路由没有匹配的时候会出现页面白屏的情况,为了处理这种情况可以配置 "无匹配" 路由,通常也叫做 "兜底路由"。
javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Home from './pages/Home';
import About from './pages/About';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
// 无匹配页面
const NoMatch = () => {
return (
<div>
<h2>Nothing to see here!</h2>
</div>
);
}
root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="home" element={<Home />} />
<Route path="about" element={<About />} />
{/* 无匹配路由 */}
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
</BrowserRouter>
);
动态链接
使用 NavLink 代替 Link 将链接显示为用户正在查看的状态。
javascript
// App.css
.hightStyle {
color: red;
}
.normalStyle {
color: black;
}
// App.tsx
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, NavLink, Outlet } from 'react-router-dom';
function App() {
const navStyle = ({ isActive }: { isActive: boolean }) => {
return {
color: isActive ? 'red' : 'black'
}
}
return (
<div className="App">
<nav>
<h2>App</h2>
<NavLink style={ navStyle } to="/home">Home</NavLink> |
<NavLink style={ navStyle } to="/about">About</NavLink>|
<NavLink className={ ({ isActive }) => isActive ? 'hightStyle' : 'normalStyle' } to="/home">Home</NavLink> |
<NavLink className={ ({ isActive }) => isActive ? 'hightStyle' : 'normalStyle' } to="/about">About</NavLink>
</nav>
{/* 承接子路由内容 */}
<Outlet />
</div>
);
}
export default App;
动态路由
javascript
import React, { useEffect, useRef, useState } from 'react';
import './App.css';
import { Link, NavLink, Outlet, useParams, useRoutes } from 'react-router-dom';
const Home = () => <h1>Home Page</h1>;
const About = () => <h1>About Page</h1>;
const User = () => {
const params = useParams();
console.log('params',params)
return <h1>User Page</h1>
};
// 路由配置函数
const routes = [
{ path: '/home', element: <Home /> },
{ path: '/about', element: <About /> },
{
path: '/user/:id',
element: <User />,
},
];
function App() {
// 创建动态路由
const element = useRoutes(routes);
return (
<div className="App">
<nav>
<h2>App Layout</h2>
{element}
</nav>
<Outlet />
</div>
);
}
export default App;
路由参数
获取路由跳转路径参数
javascript
<Routes>
<Route path="/" element={<App />}>
<Route path="home" element={<Home />} />
<Route path="about" element={<About />}>
{/* path传参 */}
<Route path=":id" element={<About />} />
</Route>
{/* 无匹配路由 */}
<Route path="*" element={<NoMatch />} />
</Route>
</Routes>
// 配置链接
<Link to="/about/11">about</Link> |
<NavLink to="/about/11">about</NavLink> |
// 获取参数
const usePrams = useParams();
console.log(usePrams);
获取路由跳转params参数
javascript
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
// Home.tsx
const Home = () => {
const navigate = useNavigate();
return (
<div>
<h2>Home</h2>
<Link to="/about" state={{ name: "hello" }}>about</Link> |
<NavLink to="/about" state={{ name: "hello" }}>about</NavLink>
</div>
)
}
// About.tsx
const About = () => {
// 获取params
const params = useLocation();
console.log(params);
return (
<div>
<h2>About</h2>
</div>
)
}
获取URL后?拼接的参数
javascript
import { useSearchParams } from "react-router-dom";
const Home = () => {
const [searchParams, setSearchParams] = useSearchParams();
return (
<div>
<h2>Home</h2>
<input type="text" value={searchParams.get("name") || ""} onChange={(e) => setSearchParams({ name: e.target.value })} />
</div>
)
}
export default Home;
通过 useSearchParams 读取和操作拼接在路由后的搜索参数
useSearchParams
返回一个URLSearchParams
与setSearchParams()
setSearchParams()
将?name=...
搜索参数放在 URL 中并重新渲染路由器
编程式导航
路由跳转
编程式导航使用 useNavigate 进行路由跳转
javascript
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
// Home.tsx
const Home = () => {
// 使用导航
const navigate = useNavigate();
return (
<div>
<h2>Home</h2>
<button onClick={() => {
// 跳转about
navigate('/about')
}}>push to About</button>
</div>
)
}
获取参数
编程式导航使用 useNavigate 进行路由跳转传参,传递的参数放在 state 中
javascript
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
// Home.tsx
const Home = () => {
const navigate = useNavigate();
return (
<div>
<h2>Home</h2>
<button onClick={() => {
navigate('/about', { state: { name: "hello" } })
}}>push to About</button>
</div>
)
}
获取参数
javascript
// About.tsx
import { Link, NavLink, useNavigate, useLocation } from "react-router-dom";
const About = () => {
// 获取params
const params = useLocation();
console.log(params);
return (
<div>
<h2>About</h2>
</div>
)
友情提示
见原文:【React】React Router)
本文同步自微信公众号 "程序员小溪" ,这里只是同步,想看及时消息请移步我的公众号,不定时更新我的学习经验。