React 全栈体系(八)
第四章 React ajax
三、案例 – github 用户搜索
2. 代码实现
2.3 axios 发送请求
Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from 'axios'export default class Search extends Component {search = () => {//获取用户的输入(连续解构赋值+重命名)const { keyWordElement:{value:keyword} } = thisconsole.log(keyword);//发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then(response => {console.log('c', response.data);},error => {console.log('d', error);})}render() {return (<section className="jumbotron"><h3 className="jumbotron-heading">Search Github Users</h3><div><input ref={c => this.keyWordElement = c} type="text" placeholder="enter the name you search" /> <button onClick={this.search}>Search</button></div></section>);}
}
2.4 展示数据
2.4.1 App
/* src/App.jsx */
import React, { Component } from "react";
import Search from "./components/Search";
import List from "./components/List";export default class App extends Component {state = {users:[]} //初始化状态,users初始值为数组saveUsers = (users)=>{this.setState({users})}render() {const {users} = this.statereturn (<div className="container"><Search saveUsers={this.saveUsers}/><List users={users}/></div>);}
}
2.4.2 Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from 'axios'export default class Search extends Component {search = () => {//获取用户的输入(连续解构赋值+重命名)const { keyWordElement:{value:keyword} } = this//发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then(response => {this.props.saveUsers(response.data.items)},error => {console.log('d', error);})}render() {return (<section className="jumbotron"><h3 className="jumbotron-heading">Search Github Users</h3><div><input ref={c => this.keyWordElement = c} type="text" placeholder="enter the name you search" /> <button onClick={this.search}>Search</button></div></section>);}
}
2.4.3 List
/* src/components/List/index.jsx */
import React, { Component } from "react";
import "./index.css";export default class List extends Component {render() {return (<div className="row">{this.props.users.map((userObj) => {return (<div key={userObj.id} className="card"><a rel="noreferrer" href={userObj.html_url} target="_blank"><imgalt="head_portrait"src={userObj.avatar_url}style={{ width: "100px" }}/></a><p className="card-text">{userObj.login}</p></div>);})}</div>);}
}
2.5 完成案例
2.5.1 App
/* src/App.jsx */
import React, { Component } from "react";
import Search from "./components/Search";
import List from "./components/List";export default class App extends Component {state = {//初始化状态users: [], //users初始值为数组isFirst: true, //是否为第一次打开页面isLoading: false, //标识是否处于加载中err: "", //存储请求相关的错误信息};//更新App的stateupdateAppState = (stateObj) => {this.setState(stateObj);};render() {const { users } = this.state;return (<div className="container"><Search updateAppState={this.updateAppState} /><List {...this.state} /></div>);}
}
2.5.2 Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import axios from "axios";export default class Search extends Component {search = () => {//获取用户的输入(连续解构赋值+重命名)const {keyWordElement: { value: keyword },} = this;//发送请求前通知App更新状态this.props.updateAppState({ isFirst: false, isLoading: true });//发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then((response) => {//请求成功后通知App更新状态this.props.updateAppState({isLoading: false,users: response.data.items,});},(error) => {//请求失败后通知App更新状态this.props.updateAppState({ isLoading: false, err: error.message });});};render() {return (<section className="jumbotron"><h3 className="jumbotron-heading">Search Github Users</h3><div><inputref={(c) => (this.keyWordElement = c)}type="text"placeholder="enter the name you search"/> <button onClick={this.search}>Search</button></div></section>);}
}
2.5.3 List
/* src/components/List/index.jsx */
import React, { Component } from "react";
import "./index.css";export default class List extends Component {render() {const { users, isFirst, isLoading, err } = this.props;return (<div className="row">{isFirst ? (<h2>Welcome, enter a keyword and then click search!</h2>) : isLoading ? (<h2>Loading......</h2>) : err ? (<h2 style={{ color: "red" }}>{err}</h2>) : (users.map((userObj) => {return (<div key={userObj.id} className="card"><a rel="noreferrer" href={userObj.html_url} target="_blank"><imgalt="head_portrait"src={userObj.avatar_url}style={{ width: "100px" }}/></a><p className="card-text">{userObj.login}</p></div>);}))}</div>);}
}
四、消息订阅-发布机制
1. 工具库
- PubSubJS
2. 下载
- npm install pubsub-js --save
3. 使用
- import PubSub from ‘pubsub-js’ //引入
- PubSub.subscribe(‘delete’, function(data){ }); //订阅
- PubSub.publish(‘delete’, data) //发布消息
4. github 用户搜索代码重构
4.1 App
/* src/App.jsx */
import React, { Component } from "react";
import Search from "./components/Search";
import List from "./components/List";export default class App extends Component {render() {return (<div className="container"><Search /><List /></div>);}
}
4.2 Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import PubSub from "pubsub-js";
import axios from "axios";export default class Search extends Component {search = () => {//获取用户的输入(连续解构赋值+重命名)const {keyWordElement: { value: keyword },} = this;//发送请求前通知List更新状态PubSub.publish("alex", { isFirst: false, isLoading: true });//发送网络请求axios.get(`https://api.github.com/search/users?q=${keyword}`).then((response) => {//请求成功后通知List更新状态PubSub.publish("alex", {isLoading: false,users: response.data.items,});},(error) => {//请求失败后通知List更新状态PubSub.publish("alex", { isLoading: false, err: error.message });});};render() {return (<section className="jumbotron"><h3 className="jumbotron-heading">Search Github Users</h3><div><inputref={(c) => (this.keyWordElement = c)}type="text"placeholder="enter the name you search"/> <button onClick={this.search}>Search</button></div></section>);}
}
4.3 List
/* src/components/List/index.jsx */
import React, { Component } from "react";
import PubSub from "pubsub-js";
import "./index.css";export default class List extends Component {state = {//初始化状态users: [], //users初始值为数组isFirst: true, //是否为第一次打开页面isLoading: false, //标识是否处于加载中err: "", //存储请求相关的错误信息};componentDidMount() {this.token = PubSub.subscribe("alex", (_, stateObj) => {this.setState(stateObj);});}componentWillUnmount() {PubSub.unsubscribe(this.token);}render() {const { users, isFirst, isLoading, err } = this.state;return (<div className="row">{isFirst ? (<h2>Welcome, enter a keyword and then click search!</h2>) : isLoading ? (<h2>Loading......</h2>) : err ? (<h2 style={{ color: "red" }}>{err}</h2>) : (users.map((userObj) => {return (<div key={userObj.id} className="card"><a rel="noreferrer" href={userObj.html_url} target="_blank"><imgalt="head_portrait"src={userObj.avatar_url}style={{ width: "100px" }}/></a><p className="card-text">{userObj.login}</p></div>);}))}</div>);}
}
五、扩展:Fetch
1. 文档
- https://github.github.io/fetch/
2. 特点
- fetch: 原生函数,不再使用 XmlHttpRequest 对象提交 ajax 请求
- 老版本浏览器可能不支持
3. 相关 API
3.1 GET 请求
fetch(url).then(function(response) {return response.json()}).then(function(data) {console.log(data)}).catch(function(e) {console.log(e)});
3.2 POST 请求
fetch(url, {method: "POST",body: JSON.stringify(data),
}).then(function(data) {console.log(data)
}).catch(function(e) {console.log(e)
})
4. github 用户搜索代码 - fetch
Search
/* src/components/Search/index.jsx */
import React, { Component } from "react";
import PubSub from "pubsub-js";export default class Search extends Component {search = async()=>{//获取用户的输入(连续解构赋值+重命名)const {keyWordElement:{value:keyWord}} = this//发送请求前通知List更新状态PubSub.publish('alex',{isFirst:false,isLoading:true})//#region 发送网络请求---使用axios发送/* axios.get(`https://api.github.com/search/users?q=${keyWord}`).then(response => {//请求成功后通知List更新状态PubSub.publish('alex',{isLoading:false,users:response.data.items})},error => {//请求失败后通知App更新状态PubSub.publish('alex',{isLoading:false,err:error.message})}) *///#endregion//发送网络请求---使用fetch发送(未优化)/* fetch(`https://api.github.com/search/users?q=${keyWord}`).then(response => {console.log('联系服务器成功了');return response.json()},error => {console.log('联系服务器失败了',error);return new Promise(()=>{})}).then(response => {console.log('获取数据成功了',response);},error => {console.log('获取数据失败了',error);}) *///发送网络请求---使用fetch发送(优化)try {const response= await fetch(`https://api.github.com/search/users?q=${keyWord}`)const data = await response.json()PubSub.publish('alex',{isLoading:false,users:data.items})} catch (error) {PubSub.publish('alex',{isLoading:false,err:error.message})}}render() {return (<section className="jumbotron"><h3 className="jumbotron-heading">Search Github Users</h3><div><inputref={(c) => (this.keyWordElement = c)}type="text"placeholder="enter the name you search"/> <button onClick={this.search}>Search</button></div></section>);}
}
六、总结
1.设计状态时要考虑全面,例如带有网络请求的组件,要考虑请求失败怎么办。
2.ES6小知识点:解构赋值+重命名let obj = {a:{b:1}}const {a} = obj; //传统解构赋值const {a:{b}} = obj; //连续解构赋值const {a:{b:value}} = obj; //连续解构赋值+重命名
3.消息订阅与发布机制1.先订阅,再发布(理解:有一种隔空对话的感觉)2.适用于任意组件间通信3.要在组件的componentWillUnmount中取消订阅
4.fetch发送请求(关注分离的设计思想)try {const response= await fetch(`/api1/search/users2?q=${keyWord}`)const data = await response.json()console.log(data);} catch (error) {console.log('请求出错',error);}
相关文章:
React 全栈体系(八)
第四章 React ajax 三、案例 – github 用户搜索 2. 代码实现 2.3 axios 发送请求 Search /* src/components/Search/index.jsx */ import React, { Component } from "react"; import axios from axiosexport default class Search extends Component {search …...
 
4.开放-封闭原则
这个原则其实是有两个特征,一个是说‘对于扩展是开放的(Open for extension),另一个是说‘对于更改是封闭的(Closed for modification)[ASD]。...
oracle递归with子句
比如现在想获取开始日期到结束日期每个月的月底日期,这个时候可以通过递归实现: --通过递归with子句获取开始日期到结束日期每个月的月末日期 WITH date_range (month_start, month_end) AS (SELECT TRUNC(to_date(bdate,yyyy-mm-dd), MM),LAST_DAY(to_…...
 
如何在Proteus进行STM32F103C8T6模拟以及keil5开发
一、下载Proteus 8和keil5 最新版 Proteus 8.15 Professional 图文安装教程(附安装包)_proteus密钥_main工作室的博客-CSDN博客Keil uVision5 5.38官方下载、安装及注册教程_keil uvision5下载_这是乐某的博客-CSDN博客 二、新建STM32F103C8项目 接下来…...
 
C# OpenCvSharp 图片模糊检测(拉普拉斯算子)
效果 项目 代码 using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Windows.Forms.VisualStyl…...
 
志高团队:广阔前景 全新的投资理财体验
当今时代,数字金融迅猛发展,投资理财领域正在经历前所未有的重大变革。作为加拿大华企联合会控股旗下的重要项目,恒贵即将启动,旨在为广大投资者带来全新的投资理财体验。这一创新项目的优势和广阔前景受到了业内观察机构的广泛关注和期待。 恒贵作为一家全新的P2C多元化投资理…...
 
基于自编译的onlyoffice镜像,关于修改字体的问题
基于自编译的onlyoffice镜像,关于修改字体的问题 自编译onlyoffice镜像来自于 https://blog.csdn.net/Gemini1995/article/details/132427908 该镜像里面没有documentserver-generate-allfonts.sh文件,所以需要自己创建一个(建议放在/usr/b…...
 
1.wifi开发,wifi连接初次连接电脑没有识别,搭建环境
wifi连接初次连接电脑没有识别 1.不识别可能是线的问题,即使wifi的灯亮了,虽然串口却没有找到。所以解决方法就是重新来一个usb的线 一。初步使用 (1)使用ESP烧写工具(选择esp8266) (2…...
 
【JAVA-Day25】解密进制转换:十进制向R进制和R进制向十进制的过程
解密进制转换:十进制向R进制和R进制向十进制的过程 一、什么是进制转换1.1 进制1.2 进制转换 二、十进制转R进制2.1 转换算法2.2 示例代码 三、R进制转十进制3.1 转换算法3.2 示例代码 四、总结参考资料 ) 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的…...
牛客网字节面试算法刷题记录
NC78 反转链表 public ListNode ReverseList (ListNode head) {if(headnull) return head;ListNode phead.next,q,tailhead;tail.next null;while(p!null){q p.next;p.next tail;tail p;p q;}return tail;} NC140 排序 冒泡排序 public int[] MySort (int[] arr) {for…...
 
QT连接Sqlite
使用QTCreator; 根据资料,Qt自带SQLite数据库,不需要再单独安装,默认情况下,使用SQLite版本3,驱动程序为***QSQLITE***; 首先创建项目;在 Build system 中应选中qmake,…...
 
ChatGPT AIGC 完成各省份销售动态可视化分析
像这样的动态可视化由人工智能ChatGPT AIGC结合前端可视化技术就可以实现。 Prompt:请使用HTML,JS,Echarts 做一个可视化分析的案例,地图可视化,数据可以随机生成,请写出完整的代码 完整代码复制如下: <!DOCTYPE html> <html> <head><meta char…...
 
基于SpringBoot+Vue的餐饮管理系统设计与实现
前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…...
2023 亲测好用版VScode配置文件
tasks.json {"tasks": [{"type": "cppbuild","label": "g++",// 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc 和launch中preLaunchTask保持一致// "command": "D:/Users/Downloads/ming…...
 
jmeter基础压力教程
Jmeter基础压力测试教程 一、安装Jmeter; 安装需求:1. JDK 8.0.91安装包(最新即可,配置环境变量) 2. Badboy2.25脚本录制工具(注:Jmeter3.0与badboy2.0不兼容) Jmerter安装包…...
 
图片格式大全
青春不能回头,青春也没有终点。 大全介绍 图片格式有多种,每种格式都有其独特的特性和用途。以下是一些常见的图片格式以及它们的介绍: JPEG(Joint Photographic Experts Group): 文件扩展名:…...
 
5.14.1.2 Get Log Page – Smart Log
SMART / Health Information (Log Identifier 02h) smart log 可通过nvme cli获取如下: 同样也可以通过get-log 命令获取到原始数据如下: 此日志页用于提供SMART和常用的helath 信息。所提供的信息在控制器的使用寿命内,并在整个power cycle前后都保留。要访问控制器日志…...
 
【深度学习实验】线性模型(一):使用NumPy实现简单线性模型:搭建、构造损失函数、计算损失值
#【中秋征文】程序人生,中秋共享# 目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 定义线性模型linear_model 2. 定义损失函数loss_function 3. 定义数据 4. 调用函数 一、实验介绍 使用Numpy实现 线性模型搭…...
 
springcloud3 分布式事务-seata的四种模式总结以及异地容灾
一 seata四种模式比较 1.1 seata的4种模式比较 二 seata的高可用 2.1架构 1.建TC服务集群非常简单,启动多个TC服务,注册到nacos即可。 2.做异地多机房容灾,比如一个TC集群在上海,另一个TC集群在杭州, 3.微服务基…...
 
【办公类-16-06】20230901大班运动场地分配表-斜线排列、5天循环、不跳节日,手动修改节日”(python 排班表系列)
背景需求: 大班组长发来一个“运动排班”的需求表:“就是和去年一样的每个班的运动排班,就因为今年大班变成7个班,删掉一个场地,就要重新做一份,不然我就用去年的那份了(8个大班排班࿰…...
 
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
 
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
 
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
 
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
 
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
 
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
 
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
 
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
