随意使用您选择的打包器,例如 Create React App
1
| npx create-react-app router-tutorial
|
然后安装 React Router 依赖项:
1 2
| cd router-tutorial npm install react-router-dom@6 history@5
|
然后编辑你的App.js,让它变得很无聊:
1 2 3 4 5 6 7
| export default function App() { return ( <div> <h1>Bookkeeper!</h1> </div> ); }
|
最后,确认index.js
or main.jsx
(取决于你的打包工具)是可用的:
root渲染App
1 2 3 4 5 6
| import { render } from "react-dom"; import App from "./App";
const rootElement = document.getElementById("root"); render(<App />, rootElement);
|
然后是删了一点东西
启动您的React应用:
连接路由
首先,我们想把你的应用连接到路由: import ‘ BrowserRouter ‘,并用它包裹你的整个应用。(修改index.js)
1 2 3 4 5 6 7 8 9 10 11
| import { render } from "react-dom"; import { BrowserRouter } from "react-router-dom"; import App from "./App";
const rootElement = document.getElementById("root"); render( <BrowserRouter> <App /> </BrowserRouter>, rootElement );
|
应用程序中没有任何变化,但现在我们已准备好开始处理路由。
添加一些链接
打开 src/App.js、导入 Link 并添加一些全局导航。注:在本教程中不要对待样式太认真,我们只是为了方便而使用内联样式,你可以根据需要设置样式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { Link } from "react-router-dom";
export default function App() { return ( <div> <h1>Bookkeeper</h1> <nav style={{ borderBottom: "solid 1px", paddingBottom: "1rem" }} > <Link to="/invoices">Invoices</Link> |{" "} <Link to="/expenses">Expenses</Link> </nav> </div> ); }
|
单击链接和后退/前进按钮。React Router 现在正在控制 URL!
我们还没有在 URL 更改时呈现任何路由,但 Link 可以更改 URL,而不会导致整个页面重新加载。
添加一些路由
添加几个新文件:
现在在文件中加入以下代码:
expenses.jsx
1 2 3 4 5 6 7
| export default function Expenses() { return ( <main style={{ padding: "1rem 0" }}> <h2>Expenses</h2> </main> ); }
|
invoices.jsx
1 2 3 4 5 6 7
| export default function Invoices() { return ( <main style={{ padding: "1rem 0" }}> <h2>Invoices</h2> </main> ); }
|
最后,让我们通过在main.jsx
或者index.js
中创建我们的第一个“路由配置”来让 React Router 在不同的 URL 上呈现我们的界面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { render } 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";
const rootElement = document.getElementById("root"); render( <BrowserRouter> <Routes> <Route path="/" element={<App />} /> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />} /> </Routes> </BrowserRouter>, rootElement );
|
注意:当路由为”/“时它渲染App组件,在”/invoices”时它渲染Invoices组件。
所以到这里我们可以看出,点击后会整页都会变换掉
嵌套路由
你可能已经注意到,当点击链接时,“App”中的布局会消失。共享布局是一件令人头疼的事情。我们已经知道,大多数UI都是一系列嵌套布局,这些布局总会映射到URL上,所以这个思路被直接植入到React Router中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import { render } 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";
const rootElement = document.getElementById("root"); render( <BrowserRouter> <Routes> <Route path="/" element={<App />}> <Route path="expenses" element={<Expenses />} /> <Route path="invoices" element={<Invoices />} /> </Route> </Routes> </BrowserRouter>, rootElement );
|
当路由有子节点时,它会做两件事:
- 它嵌套了 URL (
"/" + "expenses"
和 "/" + "invoices"
) - 当子路由匹配时,它将嵌套共享布局的 UI 组件:
但是,为了使(2)生效,我们需要在App.jsx“父”路由中渲染一个
组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { Outlet, Link } from "react-router-dom";
export default function App() { return ( <div> <h1>Bookkeeper</h1> <nav style={{ borderBottom: "solid 1px", paddingBottom: "1rem" }} > <Link to="/invoices">Invoices</Link> |{" "} <Link to="/expenses">Expenses</Link> </nav> <Outlet /> </div> ); }
|
现在再次单击。父路由 ( App.js) 仍然存在,而 <Outlet>
在两个子路由 (<Invoices>
和 <Expenses>
)之间切换! 正如我们稍后将看到的,这适用于路由层次结构的任何级别,并且非常强大。
列出发票
通常你会从某个地方的服务器获取数据,但在本教程中,让我们造一些数据,这样我们就可以专注于路由。
创建一个文件src/data.js并将其复制/粘贴到那里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| let invoices = [ { name: "Santa Monica", number: 1995, amount: "$10,800", due: "12/05/1995" }, { name: "Stankonia", number: 2000, amount: "$8,000", due: "10/31/2000" }, { name: "Ocean Avenue", number: 2003, amount: "$9,500", due: "07/22/2003" }, { name: "Tubthumper", number: 1997, amount: "$14,000", due: "09/01/1997" }, { name: "Wide Open Spaces", number: 1998, amount: "$4,600", due: "01/27/2998" } ];
export function getInvoices() { return invoices; }
|
现在我们可以在发票路由中使用它。让我们也添加一些样式来获得侧边栏导航布局。随意复制/粘贴所有这些,但要特别注意 <Link>
组件需要 to 属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import { Link } from "react-router-dom"; import { getInvoices } from "../data";
export default function Invoices() { let invoices = getInvoices(); return ( <div style={{ display: "flex" }}> <nav style={{ borderRight: "solid 1px", padding: "1rem" }} > {invoices.map(invoice => ( <Link style={{ display: "block", margin: "1rem 0" }} to={`/invoices/${invoice.number}`} key={invoice.number} > {invoice.name} </Link> ))} </nav> </div> ); }
|