当前位置: 首页 > 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…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

(一)单例模式

一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...