React路由
"react-router-dom": "^6.2.2"
-
安装react-router-dom
-
在React项目里安装
react-router-domnpm install react-router-dom@6 -
引入标签
import { BrowserRouter, Routes, Route } from "react-router-dom"; -
基本用法
src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Routes, Route, } from "react-router-dom"; import App from './App'; import Expenses from "./routes/expenses"; import Invoices from "./routes/invoices"; ReactDOM.render( <BrowserRouter> <Routes> <Route path="/" element={<App />} /> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />} /> </Routes> </BrowserRouter>, document.getElementById('root') );
-
-
使用嵌套路由
-
需要引入
Outletimport { Outlet, Link } from "react-router-dom"; -
代码
src/App.js import { Outlet, Link } from "react-router-dom"; function App() { return ( <div className="App"> <header className="App-header"> <nav> <Link to="/invoices">Invoices</Link> |{" "} <Link to="/expenses">Expenses</Link> </nav> <Outlet /> </header> </div> ); } export default App; -
将expenses和invoices作为根路由的子级,作为子级它们共享App组件里的样式
src/index.js import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter, Routes, Route, } from "react-router-dom"; import App from './App'; import Expenses from "./routes/expenses"; import Invoices from "./routes/invoices"; ReactDOM.render( <BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />} /> </Route> </Routes> </BrowserRouter>, document.getElementById('root') );
-
-
添加不匹配路由
-
当没有路由匹配时,便会匹配
*<Routes> <Route path="/" element={<App />}> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />} /> <Route path="*" element={ <main style={{ padding: "1rem" }}> <p>没有匹配的路由!</p> </main> } /> </Route> </Routes>
-
-
读取URL参数
-
我们要读取
/invoices/2005中的2005,先在invoices下创建一个子路由,值命名为invoiceId。注意:Invoices 和 Invoice 是两个不同的组件<Routes> <Route path="/" element={<App />}> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />}> <Route path=":invoiceId" element={<Invoice />} /> </Route> <Route path="*" element={ <main style={{ padding: "1rem" }}> <p>没有匹配的路由!</p> </main> } /> </Route> </Routes> -
在 Invoices 组件中增加一个 Outlet 用来显示 Invoice
import { Outlet, Link } from "react-router-dom"; export default function Invoices() { return ( <main style={{ padding: "1rem 0", display: "flex" }} > <div style={{ marginRight: "100px", display: "flex", flexDirection: "column"}}> <Link to="/invoices/2005">2005</Link> <Link to="/invoices/2006">2006</Link> <Link to="/invoices/2007">2007</Link> <Link to="/invoices/2008">2008</Link> <Link to="/invoices/2009">2009</Link> <Link to="/invoices/2010">2010</Link> </div> <div> <Outlet /> </div> </main> ); } -
在 Invoice 中引入
useParams用来读取值import { useParams } from "react-router-dom"; export default function Invoices() { let params = useParams(); let invoiceId = parseInt(params.invoiceId, 10); return ( <main> <div>invoiceId: {invoiceId}</div> </main> ); }
-
-
索引路由
-
当父路由匹配,但子路由不匹配时,便会匹配索引路由。例如:我们访问 /invoices,但因为没有子路由匹配,所以不展示页面,这时如果有索引路由便会展示索引路由。索引路由是父路由的默认子路由。
<BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />}> <Route index element={ <main style={{ padding: "1rem" }}> <p>请选择一张发票</p> </main> } /> <Route path=":invoiceId" element={<Invoice />} /> </Route> </Route> <Route path="*" element={ <main style={{ padding: "1rem" }}> <p>没有匹配的路由!</p> </main> }> </Route> </Routes> </BrowserRouter>
-
-
NavLink
-
用来高亮当前路由的链接
import { NavLink } from "react-router-dom"; // 如果当前路径是 /invoices/2005,那么它的className就会变成"red" <NavLink className={({ isActive }) => isActive ? "red" : "blue" to="/invoices/2005"}>2005</NavLink> <NavLink style={({ isActive }) => ({ display: "block", margin: "1rem 0", color: isActive ? "red" : "", })} to="/invoices/2005"} > 2005 </NavLink>
-
-
搜索参数
-
引入
useSearchParamsimport { useSearchParams } from "react-router-dom"; -
通过
searchParams.get()获取参数。通过setSearchParams({});获取参数let [searchParams, setSearchParams] = useSearchParams(); // 当前URL /invoices/2005?filter=test searchParams.get("filter") // test // 设置URL为 /invoices/2005?filter=200 setSearchParams({ filter: 200 });
-