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

WarcraftHelper:魔兽争霸III终极兼容性修复工具,5大核心功能全面优化游戏体验

WarcraftHelper&#xff1a;魔兽争霸III终极兼容性修复工具&#xff0c;5大核心功能全面优化游戏体验 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper …...

突破性能瓶颈:深入理解 JavaScript TypedArray

&#x1f680; 突破性能瓶颈&#xff1a;深入理解 JavaScript TypedArray &#x1f914; 为什么普通 Array 不够用&#xff1f; 在 JavaScript 中&#xff0c;普通的 Array 是一个非常灵活但“沉重”的对象&#xff1a; 动态类型&#xff1a;它可以同时存放数字、字符串、对…...

基于Next.js与Prisma构建宠物社区应用:全栈开发实战解析

1. 项目概述&#xff1a;一个为宠物爱好者打造的社区应用最近在GitHub上闲逛&#xff0c;发现了一个挺有意思的开源项目&#xff0c;叫jtsang4/happypaw。光看名字&#xff0c;“Happy Paw”&#xff08;快乐的爪子&#xff09;&#xff0c;就能猜到这八成是和宠物相关的。点进…...

ctf show web 入门43

打开靶场代码逻辑如下&#xff1a; if(!preg_match(“/\ |/|cat/i”, $c)) 它过滤了三个关键内容&#xff1a; \ (空格)&#xff1a;你不能直接在命令中使用空格&#xff08;例如 ls -l 或 cat flag 都会失败&#xff09;。 / (正斜杠)&#xff1a;你不能使用路径符号&#xf…...

Awesome-Robotics-3D:机器人3D视觉资源精选与高效利用指南

1. 项目概述&#xff1a;一个机器人学3D视觉的“藏宝图” 如果你正在机器人、自动驾驶或者三维感知领域摸爬滚打&#xff0c;并且时常为了找一个靠谱的开源实现、一篇奠基性的论文&#xff0c;或者一个高质量的数据集而翻遍GitHub、arXiv和各大实验室主页&#xff0c;那么你很可…...

仅限前500名获取|Midjourney Blackberry印相专业级Prompt模板包(含EXIF元数据模拟指令)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney Blackberry印相的美学溯源与技术本质 Blackberry印相&#xff08;Blackberry Photographic Process&#xff09;并非真实存在的传统暗房工艺&#xff0c;而是Midjourney社区中对一类高对比、…...

【限时解密】Photoshop 25.5 Beta隐藏功能+Midjourney API私有化接入指南(含已验证Webhook配置模板与错误码速查表)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney与Photoshop整合方案的演进逻辑与架构全景 随着生成式AI在创意工作流中的深度渗透&#xff0c;Midjourney与Photoshop的协同已从“图像导出→手动精修”的离散模式&#xff0c;演进为基于API…...

从音频处理到IoT数据:用scipy.signal.resample_poly搞定实际项目中的采样率转换

从音频处理到IoT数据&#xff1a;用scipy.signal.resample_poly搞定实际项目中的采样率转换 采样率转换是数字信号处理中的常见需求&#xff0c;无论是音频处理、传感器数据分析还是通信系统仿真&#xff0c;都会遇到不同采样率设备间的数据交互问题。想象一下&#xff0c;当你…...

为什么92%的数据分析师还没用上Gemini Sheets功能?—— 一份被谷歌官方忽略的AI分析落地清单

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Gemini Sheets数据分析的现状与认知断层 Gemini Sheets 作为 Google Workspace 生态中新兴的 AI 增强型电子表格工具&#xff0c;正逐步替代传统 Sheets 的部分分析场景。然而&#xff0c;当前用户实践…...

Davinci vs. 其他开源BI工具(Superset/Metabase)实战对比:我们团队为什么最终选了它?

Davinci vs. 其他开源BI工具实战对比&#xff1a;技术选型的深度思考 在数据驱动决策的时代&#xff0c;企业级BI工具的选择直接影响着数据分析的效率和深度。当我们团队面临开源BI工具选型时&#xff0c;Davinci、Apache Superset和Metabase成为了主要候选对象。经过三个月的实…...