安装
以 create-react-app --template typescript 构建的项目模板;
npm intsall react-router react-router-dom
(此处为 v6 版本)
基础使用
-
路由的定义和跳转是分离的,此处直接将路由定义在了入口文件
index.tsx
里面import { BrowserRouter, Route, Routes } from 'react-router-dom'; React.render( <React.StrictMode> <BrowserRouter> <Routes> /*element 代表该路由渲染的组件*/ <Route path="/" element={<App />}></Route> <Route path="message" element={<Message />}></Route> <Route path="todoList" element={<TodoList />}></Route> </Routes> </BrowserRouter> </React.StrictMode>, document.getElementById('root') )
-
路由跳转链接放在
App.tsx
里面<ul style={{display: 'flex'}}> <li style={{width: '200px', textAlign: 'center'}}> <Link to={'/message'}>Message</Link> </li> <li style={{width: '200px', textAlign: 'center'}}> <Link to={'/todoList'}>TodoList</Link> </li> </ul>
以上代码,会跳转到三个路由 localhost:8080/
、localhost: 8080/message
、localhost:8080/todoList
,且三个路由所展示的UI是互相独立的
嵌套路由
嵌套路由需要改动两个地方
- 路由定义的嵌套
- 在路由跳转的地方定义一个
Outlet 组件
,相当于路由坑,用于存储和和切换子路由对应的组件
// index.tsx
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route path='/' element={<App></App>}>
<Route path='message' element={<Message></Message>}></Route>
<Route path='todoList' element={<TodoList></TodoList>}>
<Route
/*index 是父路由默认渲染的界面,当父路由匹配子路由匹配不到的时候,就展示该界面*/
index
element={
<main style={{ padding: "1rem" }}>
<p>Select an invoice</p>
</main>
}
/>
<Route path=':id' element={<Todo></Todo>}></Route>
</Route>
/*找不到相应组件后显示的界面*/
<Route path='*' element={
<main style={{ padding: '1rem' }}>
<p>404</p>
</main>
}></Route>
</Route>
</Routes>
</BrowserRouter>
</React.StrictMode>,
document.getElementById('root')
);
// App.tsx
<ul style={{display: 'flex'}}>
<li style={{width: '200px', textAlign: 'center'}}>
<Link to={'/message'}>Message</Link>
</li>
<li style={{width: '200px', textAlign: 'center'}}>
<Link to={'/todoList'}>TodoList</Link>
</li>
</ul>
<Outlet></Outlet>
我觉得react-router
嵌套路由的核心就是 Outlet
组件,它可以实现在 App
组件里面切换其他组件,从而实现嵌套效果
NavLink 组件
NavLink
组件和 Link
组件基本功能是一样的,用于路由跳转,不过 NavLink
组件提供了一个 isActive
属性,可以用于分辨哪个链接处于激活状态,不止 style
可以获取, className
也可以获取到
<NavLink
style={({ isActive }) => {
return {
display: "block",
margin: "1rem 0",
color: isActive ? "red" : ""
};
}}
to={`/todoList/${invoice.number}`}
key={invoice.number}
>
{invoice.name}
</NavLink>
useParams()
在嵌套路由里面定义一个这样的路由
<Route path=':id' element={<Todo></Todo>}></Route>
可以看出 /todoList/xxx
是指向 Todo
组件的,所以可以在 Todo
组件中利用 useParams()
来获取 xxx
import {
useParams,
} from "react-router-dom";
const params = useParams();
xxx = params.id;
useSearchParams()
一个 react-router-dom 里面的 hooks
,类似于 useState
,可以理解成通过URL实现状态管理
import {
useSearchParams
} from "react-router-dom";
let [searchParams, setSearchParams] = useSearchParams();
<input
value={searchParams.get("filter") || ""}
onChange={event => {
let filter = event.target.value;
if (filter) {
setSearchParams({ filter });
} else {
setSearchParams({});
}
}}
/>
当在 input
的值变化的时候,就会动态的更改 URL
,类似于 localhost:8080/todoList/13?filter=xxx
;
useSearchParams()
会返回一个 URLSearchParams 对象
useLocation()
useLocation()
可以获取最新的路由信息
const localtion = useLocation()
// 返回如下
{
pathname: "/todoList",
search: "?filter=sa",
hash: "",
state: null,
key: "ae4cz2j"
}