当前位置: 首页 > news >正文

React 入门 02:从单页面应用到多页面应用

本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站,包括页面扩展的逻辑,React生态中最流行的路由框架react-router的基本用法以及扩展用法

文章目录

  • 一、场景说明
  • 二、基本的页面扩展
    • 页面扩展是在扩什么
  • 三、路由用法扩展:更多定制化的路由配置场景
    • 动态路由实现详情页展示
  • 四、控制路由跳转的API

一、场景说明

我们在进行网站开发的时候,大多数都是需要有多个页面展示不同内容或者提供不同功能。每个页面单独启动一个项目的做法不太现实,实际业务中是一个项目中,一个页面对应项目代码中一个代码文件,然后通过浏览器地址的不同后缀(比如/home, /about, /prodcut, /center等等)来对应到不同的代码文件,进而在浏览器上展示不同的内容和提供不同的功能。

二、基本的页面扩展

页面扩展是在扩什么

在前文介绍如何创建一个React项目并且修改页面内容时,我们已经探索到了页面渲染的逻辑,即:

  • 浏览器根据地址栏输入的地址,可以访问到我们启动的React项目
  • React项目会获取HTML页面内容中的body区域,然后将我们的应用内容通过React的渲染函数渲染到HTML中
  • 页面展示填充了具体应用内容的完整HTML

就完成了从代码到浏览器内容的关联和渲染展示。现在我们希望除了最初的App.jsx页面之外,我们还可以有更多的页面,并且通过浏览器地址栏不同的后缀来显示不同的页面。那么根据页面渲染是一种对应关系,一个地址栏会对应到一个代码文件(比如"http://localhost:5173/"对应到App.jsx),添加一个新的页面文件(比如About.jsx)是很简单的,我们需要解决的是,如何拿到地址栏的路径,能够在项目中加入一个类似if-else的操作,让不同路径对应到不同的页面代码文件。(当前不管我们在地址栏输入什么后缀,都是显示的App.jsx

这就需要往React项目里增加路由模块了,我们接下来以最流行的react-router来实现多页面扩展这件事。
首先,通过如下命令安装react-router到我们的项目中:
npm i react-router

然后在我们的入口文件main.jsx中将路由模块导入进来,并嵌入我们的应用中,如下:
在这里插入图片描述
我们通过import { BrowserRouter, Routes, Route } from "react-router"; 来导入react-router提供的路由功能模块,从名称可以看出

  • BrowserRouter的作用就是一个浏览器的路由器,也就是负责处理我们希望的从一个地址栏链接对应到一个代码文件的路由任务。
  • Routes用来渲染或者说管理一组Router,将当前地址栏的路径匹配到对应的Router
  • Router用来写明我们希望的地址栏路径代码文件之间的对应关系

于是经过上述配置后,对于根路径/,就是对应到App.jsx。可以额外试试其他路径,在配置之前我们输入任何路径都会显示App页面的内容,但是显示如果我们输入一个不存在的路径(比如/about),可以在【F12 - console】中看到如下信息提示没有找到匹配的路由:
在这里插入图片描述
这说明我们的项目中其实已经有了路由功能,现在路由功能模块找不到路径/about应该对应到哪一块代码上,就会不显示页面内容并且输出如上提示。

接下来我们添加一些页面代码内容给/about,看是否会正常显示。修改如下:
在这里插入图片描述
然后回到浏览器中,可以看到/about页面当前显示的内容如下:
在这里插入图片描述
说明我们的修改确实生效了。/about路由按照我们期望地指向了<h1>Here is About Page</h1>。如果我们希望展示更多内容,可以像App.jsx一样单独新建一个代码文件,然后将页面内容写到代码文件里,再导入到main.jsx中使用。

现在我们可以很清楚,当我们要增加一个新的页面的时候,其实就是新增一个从代码到浏览器地址的关联关系。我们具体要做的就是:增加一个页面,然后增加一个浏览器地址路径到具体页面代码文件的对应关系

三、路由用法扩展:更多定制化的路由配置场景

动态路由实现详情页展示

我们在实际开发过程中,一个页面展示的内容布局是不变的,只是页面的数据不同而已,比如:

  • 博客网站的博文详情页
  • 电商网站的商品详情页
  • 视频网站的视频播放页

关于详情页这种只是数据变化的页面,我们的实现方法一般是拿到数据之后将数据展示到对应的位置上。至于数据可以是在页面跳转前将数据传入,常见于我们说的MVC架构中;也可以是从网页请求中获取对应的数据参数,然后进行数据请求得到数据,常见于前后端分离的架构。

如果我们是从网页请求中获取的数据参数,则我们可以常见到如下两种请求方式:

  • 参数作为url请求传入:http://localhost:8080/user?user_id=1
  • restful的方式,作为路由的一部分,由路由逻辑按照指定模式去匹配获取:http://localhost:8080/user/1

如果要实现http://localhost:8080/user/1这种方式,我们可以可以使用react-router的动态路由参数,将路由配置修改如下:

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter, Routes, Route } from "react-router";
import './index.css'
import App from './App.jsx'
import Team from './Team.jsx';createRoot(document.getElementById('root')).render(<StrictMode><BrowserRouter><Routes><Route path="/" element={<App />} /><Route path="/team/:teamName" element={<Team />} /></Routes></BrowserRouter></StrictMode>
)

新增的Team.jsx代码文件内容如下:

import { useParams } from "react-router";export default function Team() {// 通过 useParams 获取路由参数// 外部路由设置了 /team/:teamName, 那么就可以得到 teamName 的值let params = useParams();return <h1>Here is Team Page About<h2>{params.teamName}</h2></h1>
}

于是回到浏览器页面,我们可以看到浏览器地址栏和页面内容对应关系对下:
在这里插入图片描述
页面代码成功获取了地址栏中的团队名称并且显示在了页面内容中。


除此之外,还有一些其他的常见用法:

  • 不同路径指向相同页面:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter, Routes, Route } from "react-router";
import './index.css'
import App from './App.jsx'createRoot(document.getElementById('root')).render(<StrictMode><BrowserRouter><Routes><Route path="/" element={<App />} /><Route path="/home" element={<App />} /><Route path="/index" element={<App />} /></Routes></BrowserRouter></StrictMode>
)
  • 嵌套路由:
    • 只替换某些部分的内容,公共内容不变,减少重复代码
    • /dashboard/profile:显示用户个人信息
    • /dashbord/settings :显示用户设置
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter, Routes, Route } from "react-router";
import './index.css'
import App from './App.jsx'
import Dashboard from './Dashboard.jsx';createRoot(document.getElementById('root')).render(<StrictMode><BrowserRouter><Routes><Route path="dashboard" element={<Dashboard />}><Route index element={<h1>Content: Home</h1>} />{/* 等价写法:<Route path="" element={<h1>Content: Home</h1>} /> */}<Route path="settings" element={<h1>Content: Setting</h1>} /></Route></Routes></BrowserRouter></StrictMode>
)

公共部分的Dashboard.jsx文件内容如下:

import { Outlet } from "react-router";export default function Dashboard() {return (<div><h1>Common Title: Dashboard</h1>{/* 渲染时 <Outlet /> 会被替换成 Home 对应的组件内容或者 Settings 对应的组件内容 */}<Outlet /></div>);
}
  • 懒加载:
    • 功能:只有当路由被访问(即用户第一次访问对应页面)的时候才加载对应页面组件
    • 优势:防止页面加载过慢以及构建应用时打包的js包过大
    • 写法
      • 不是懒加载的写法:import App from './App.jsx'
      • 懒加载写法:const App = lazy(() => import("./App"));(需要先导入lazy方法: import { lazy } from 'react';

四、控制路由跳转的API

我们也可以通过在组件中调用Router API来实现路由的跳转、回退等功能。如下:

import { useNavigate } from "react-router";function SomeComponent() {let navigate = useNavigate();return (<button onClick={() => navigate(-1)}>Go Back</button>);
}

上面的代码中我们通过react-router提供的useNavigate获取到了网站路由的导航器navigate(这是一个方法),通过调用这个方法就可以实现对路由的精准控制,传入的参数可以是指定的路由/about,也可以是距离(比如-1代表回退一个页面,1代表前进一个页面)

其他的路由控制还有:

  • 带参数跳转:
    • navigate("/some/route?search=keyword");
    • 获取参数:
      • import { useSearchParams } from "react-router";
      • const [searchParams, setSearchParams] = useSearchParams();
      • searchParams.get("search") // 得到值:keyword
  • ……

掌握了以上内容基本就可以解决实际业务开发中的大部分场景,第四部分的API不需要记忆,只需要记住「我们有办法能够通过代码逻辑来控制路由」即可。

快去试试搭建自己的多页面网站吧~


http://www.dtcms.com/a/549633.html

相关文章:

  • 石家庄网站建设找哪家好河西网站建设优化seo
  • h5网站怎么做api对接赣州人才招聘网
  • 生产管理系统详解:物料清单bom 工序,工艺路线中的工序和工艺资源他们之间有什么关联和区别
  • 发布元服务配置应用分类、标签和资质信息(仅分发手表设备)
  • 成绩查询系统如何制作?
  • 中国建设银行信用卡官网站首页个人做商机网站如何盈利
  • springboot酒店客房管理系统设计与实现(代码+数据库+LW)
  • 交叉编译工具链深度解析 --静态库与动态库编译实战指南
  • uni-app 开发APP应用媒体处理与文件管理功能
  • 网站建设scyiyou百度竞价推广一个月多少钱
  • 基于整数MCU的FOC控制定标策略深度解析
  • [HDiffPatch] 差异算法 | `serialize_compressed_diff`
  • Pycatia二次开发基础代码解析:实例名称获取与几何显示控制技术解析
  • 小迪安全v2023学习笔记(一百四十天)—— Linux系统权限篇VulnhubPATH变量NFS服务Cron任务配合SUID
  • 做网站前端wordpress打字烟花
  • 新能源汽车动力系统拆装与检测实训MR软件介绍-比亚迪秦EV标准版
  • 力扣:214. 最短回文串(Python3)
  • 基于Jdk17+SpringBoot3AI智慧教育平台,告别低效学习,AI精准导学 + 新架构稳跑
  • 论坛网站太难做没人百度推广客户端app
  • Shell实用实例2
  • Go语言:解决 “package xxx is not in std”的思路
  • 给排水干管工程量-连续测量得心应手
  • 麦克斯韦方程扩展版本,用来解释不对称情况下的公式
  • 哈尔滨网站建设的公司哪家好广安发展建设集团门户网站
  • 批量转双层PDF(可识别各种语言) 中文绿色版
  • 北京网站关键词排名销售管理软件排名
  • TCP 扫描中的“有效响应”过滤器解析
  • 我用ChatGPT,给RabbitMQ加了个连接池
  • 做电脑网站手机能显示不出来怎么办you物公馆网站建设
  • Rust 所有权:内存安全的基石与实践指南