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

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" />&nbsp;<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" />&nbsp;<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"/>&nbsp;<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"/>&nbsp;<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"/>&nbsp;<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.开放-封闭原则

这个原则其实是有两个特征&#xff0c;一个是说‘对于扩展是开放的(Open for extension)&#xff0c;另一个是说‘对于更改是封闭的(Closed for modification)[ASD]。...

oracle递归with子句

比如现在想获取开始日期到结束日期每个月的月底日期&#xff0c;这个时候可以通过递归实现&#xff1a; --通过递归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 图文安装教程&#xff08;附安装包&#xff09;_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镜像&#xff0c;关于修改字体的问题 自编译onlyoffice镜像来自于 https://blog.csdn.net/Gemini1995/article/details/132427908 该镜像里面没有documentserver-generate-allfonts.sh文件&#xff0c;所以需要自己创建一个&#xff08;建议放在/usr/b…...

1.wifi开发,wifi连接初次连接电脑没有识别,搭建环境

wifi连接初次连接电脑没有识别 1.不识别可能是线的问题&#xff0c;即使wifi的灯亮了&#xff0c;虽然串口却没有找到。所以解决方法就是重新来一个usb的线 一。初步使用 &#xff08;1&#xff09;使用ESP烧写工具&#xff08;选择esp8266&#xff09; &#xff08;2&#xf…...

【JAVA-Day25】解密进制转换:十进制向R进制和R进制向十进制的过程

解密进制转换&#xff1a;十进制向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&#xff1b; 根据资料&#xff0c;Qt自带SQLite数据库&#xff0c;不需要再单独安装&#xff0c;默认情况下&#xff0c;使用SQLite版本3&#xff0c;驱动程序为***QSQLITE***&#xff1b; 首先创建项目&#xff1b;在 Build system 中应选中qmake&#xff0c;…...

ChatGPT AIGC 完成各省份销售动态可视化分析

像这样的动态可视化由人工智能ChatGPT AIGC结合前端可视化技术就可以实现。 Prompt:请使用HTML,JS,Echarts 做一个可视化分析的案例,地图可视化,数据可以随机生成,请写出完整的代码 完整代码复制如下: <!DOCTYPE html> <html> <head><meta char…...

基于SpringBoot+Vue的餐饮管理系统设计与实现

前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f447;&#x1f3fb;…...

2023 亲测好用版VScode配置文件

tasks.json {"tasks": [{"type": "cppbuild","label": "g++",// 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc 和launch中preLaunchTask保持一致// "command": "D:/Users/Downloads/ming…...

jmeter基础压力教程

Jmeter基础压力测试教程 一、安装Jmeter&#xff1b; 安装需求&#xff1a;1. JDK 8.0.91安装包&#xff08;最新即可&#xff0c;配置环境变量&#xff09; 2. Badboy2.25脚本录制工具&#xff08;注&#xff1a;Jmeter3.0与badboy2.0不兼容&#xff09; Jmerter安装包…...

图片格式大全

青春不能回头&#xff0c;青春也没有终点。 大全介绍 图片格式有多种&#xff0c;每种格式都有其独特的特性和用途。以下是一些常见的图片格式以及它们的介绍&#xff1a; JPEG&#xff08;Joint Photographic Experts Group&#xff09;&#xff1a; 文件扩展名&#xff1a;…...

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实现简单线性模型:搭建、构造损失函数、计算损失值

#【中秋征文】程序人生&#xff0c;中秋共享# 目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 定义线性模型linear_model 2. 定义损失函数loss_function 3. 定义数据 4. 调用函数 一、实验介绍 使用Numpy实现 线性模型搭…...

springcloud3 分布式事务-seata的四种模式总结以及异地容灾

一 seata四种模式比较 1.1 seata的4种模式比较 二 seata的高可用 2.1架构 1.建TC服务集群非常简单&#xff0c;启动多个TC服务&#xff0c;注册到nacos即可。 2.做异地多机房容灾&#xff0c;比如一个TC集群在上海&#xff0c;另一个TC集群在杭州&#xff0c; 3.微服务基…...

【办公类-16-06】20230901大班运动场地分配表-斜线排列、5天循环、不跳节日,手动修改节日”(python 排班表系列)

背景需求&#xff1a; 大班组长发来一个“运动排班”的需求表&#xff1a;“就是和去年一样的每个班的运动排班&#xff0c;就因为今年大班变成7个班&#xff0c;删掉一个场地&#xff0c;就要重新做一份&#xff0c;不然我就用去年的那份了&#xff08;8个大班排班&#xff0…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...