react 是 Facebook 构建的 javascript 库,用于在单页应用程序中组合用户界面。在本教程中,我们将讨论如何正确设置路由以及如何使用 React Router 处理 React Web 应用程序中的嵌套路由。
仔细看看路由嵌套
为了清楚地解释什么是嵌套路由以及它们是如何在 React 中实现的,我创建了一个简单的网站。
在继续之前,请查看下面的应用演示。展开右侧窗口并在浏览网站时注意 URL。
基本上,这个网站背后的想法是,在首页上有一个导航菜单,其中包含指向三个页面的链接:主页、仪表板页面和产品页面。
前两个页面Home和Dashboard都有简单的路由,如下所示:/home和/dashboard。但是,在某些情况下,我们可能需要使用嵌套路由来构建我们的页面。在我们的例子中,产品页面将有多个嵌套路由来显示不同的页面。
在产品主页上,我们有一个产品搜索路径、一个显示产品列表的路径和另一个添加产品的路径。这些页面中的每一个的路由都将嵌套在/products上,如/products/add、products/all和products/search。
现在我们已经了解了什么是嵌套路由并对我们的项目有了一个概念,让我们来看看在 React 应用程序中设置它们的过程。
安装
我们将使用create-react-app
代码生成器来生成我们的 React 项目的骨架。
您需要在您的机器上安装 node >= 14.0.0 和 npm >= 5.6。要创建项目,请在终端上运行以下命令:
npx create-react-app demo-app cd demo-app
这将在demo-app
文件夹中创建您的 React 应用程序。
为了在我们的应用程序中实现路由,我们还将react-router-dom
从 npm 安装流行的库。React Router 是一个流行的 React 路由库。该库通过将应用程序 UI 的不同部分映射到唯一的 URL 路径来启用 React 应用程序中的各种组件之间的导航。
要安装 react-router 包,请运行以下命令:
npm i react-router-dom
安装软件包后,现在让我们查看我们网站的详细信息。
项目结构
我们网站的整体结构将如下所示:
demo-app ├── src │ ├── components │ ├── products │ ├── AddProduct.js │ ├── Products.js │ ├── ProductsList.js │ ├── ProductsSearch.js │ └── SingleProduct.js │ ├── Home.js // path: /home │ └── Dashboard.js // path: /dashboard │ ├── App.css │ ├── App.js │ ├── Productsdata.js │ ├── components ├── public ├── package.json └── README.md
使用此图作为参考,在该文件components
夹内创建一个文件src
夹,然后在 内components
创建Home.js和Dashboard.js文件以及products文件夹。
然后,在products文件夹中,为嵌套页面创建Products.js、AddProducts.js、ProductsList.js、SingleProduct.js和ProductSearch.js 文件。
在应用程序中实现路由
在我们开始创建 React 组件来渲染不同的页面之前,让我们先来看看我们的根组件App.js的最终版本。
我们将从导入开始:
import { BrowserRouter as Router, Link, Routes, Route } from "react-router-dom"; import "./App.css"; import Home from "./components/Home"; import Products from "./components/products/Products"; import Dashboard from "./components/Dashboard"; import ProductsSearch from "./components/products/ProductsSearch"; import AddProduct from "./components/products/AddProduct"; import SingleProduct from "./components/products/SingleProduct"; import ProductsList from "./components/products/ProductsList";
在代码的第一行,我们导入了一些核心组件,以使我们能够为我们的网站定义路由。该Router
组件将充当我们所有应用程序路由、标记和 URL 路径的包装器。Routes
用于将应用程序中定义的所有路由组合在一起。每个路由都由组件定义,该Route
组件采用 URL 路径并将该路径映射到 React 组件。
在导入下方react-router
,我们还导入了要在这些路由中渲染的各个组件。
现在,在导入下方,包含以下代码:
function App() { return ( <Router> <nav> <Link to="/"> Home </Link> <Link to="dashboard"> Login </Link> <Link to="products/search"> Products </Link> </nav> <Routes> <Route path="/" element={<Home />} /> <Route path="dashboard" element={<Dashboard />} /> <Route path="products" element={<Products />}> <Route path="search" element={<ProductsSearch />} /> <Route path="list" element={<ProductsList />} /> <Route path="add" element={<AddProduct />} /> <Route path=":id" element={<SingleProduct />} /> </Route> </Routes> </Router> ); } export default App;
为了嵌套路由,我们简单地将所有四个路由作为/ products 的子路由,从而使/products成为父路由。该组织将创建products/search、product/list、product/add和product/2等路径。
请注意, :id
最后一个路由中的 slug 表示页面是动态的:它根据 id
参数而变化。
路由嵌套最好的部分是您可以在Products
组件中定义基本布局。然后,此布局将在路由 中/products内嵌套的所有页面中重复使用。
这是App.css文件中的 CSS 代码:
@import url(https://fonts.googleapis.com/css?family=Open+Sans); .App { text-align: center; } body { padding: 0%; margin: 0%; font-family: "Open Sans", sans-serif; } nav { margin: 0; width: 100%; height: 80px; background-color: purple; display: flex; justify-content: center; align-items: center; color: white; text-decoration: none; } a { color: white; text-decoration: none; margin: 10px; font-size: 25px; } .search { width: 100%; position: relative; display: flex; } .searchTerm { width: 100%; border: 3px solid purple; border-right: none; padding: 5px; height: 20px; border-radius: 5px 0 0 5px; outline: none; color: #9dbfaf; } .searchTerm:focus { color: purple; } .searchButton { width: 40px; height: 36px; border: 1px solid purple; background: purple; text-align: center; color: #fff; border-radius: 0 5px 5px 0; cursor: pointer; font-size: 20px; } /*Resize the wrap to see the search bar change!*/ .wrap { width: 30%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .products { width: 100%; height: calc(100vh - 80px); display: flex; flex-direction: column; align-items: center; padding-top: 60px; } .productsNav { width: 70%; height: 80px; border-radius: 12px; display: flex; justify-content: center; } .productsNav a { width: 150px; height: 50px; background-color: purple; border-radius: 5px; display: flex; align-items: center; justify-content: center; } .listOfProducts { width: 100%; height: calc(100vh - 80px); display: flex; justify-content: center; padding-top: 60px; } .productsList { columns: 3 auto; display: inline-block; } .productDisplay { width: 300px; height: 300px; background-color: rgb(233, 233, 233); cursor: pointer; } * { padding-top: 0; margin-top: 0; }
在下一节中,让我们仔细看看实现基本布局。
实现嵌套路由的基本布局
我们将在src/components/products/Products.js 文件中包含以下代码:
import React from "react"; import { Link, Outlet } from "react-router-dom"; function Products() { return ( <div className="products"> <div className="productsNav"> <Link to="/products/search"> Search </Link> <Link to="/products/list"> List </Link> <Link to="/products/add"> Add </Link> </div> <Outlet /> </div> ); } export default Products;
我们从导入React
、Link
和开始Outlet
。
顾名思义,Outlet
允许你“放出”与活动路由相关的组件。例如,每当我们导航到products/add时,React Router 都会“释放”AddProduct
组件并隐藏其他三个嵌套路由。
此设置的一个含义是从组件返回的任何其他标记(在我们的示例中为导航菜单)将在所有其他嵌套路由中输出。所以导航栏也会出现在products/list和products/2中。
动态路线
回到我们在App.js中的路由结构,最后一个路由定义如下:
// other routes <Route path=":id" element={<SingleProduct />} />
这将用于根据产品的id
属性显示单个产品。
在src/components/products/SingleProduct.js中包含以下代码:
import React from "react"; import { useParams } from "react-router-dom"; import { ProductsData } from "../../ProductsData"; function ProductSingle() { const { id } = useParams(); return ( <div className="listOfProducts"> <div className="productDisplay"> <h1>{ProductsData[id - 1].name}</h1>{" "} <p>{ProductsData[id - 1].description}</p>{" "} </div> </div> ); } export default ProductSingle;
useParams
允许我们使用与活动路由相关的参数。在这里,我们从参数中解构id
属性,并使用 thisid
检索相应的产品数据ProductsData
并将其传递到模板中。
尽管在我们的例子 ProductsData
中只是来自 JavaScript 数组的假数据,但它代表了网站的数据库。因此,它可以替换为您选择的任何数据库。
我们的应用程序的最终版本可以在Codesandbox上查看。
把它概括
在本教程中,您了解了如何使用 React Router 在 React 应用程序中实现嵌套路由。
我希望本教程能帮助你更好地理解 React 中的嵌套路由。您现在应该能够使用 react-router-dom 包为您的 React 应用程序正确构建路由。
React 已成为在 Web 上工作的主要 UI 框架之一。它并非没有学习曲线,而且还有很多资源可以让您保持忙碌。本教程的源代码可在GitHub 上获得。