在 React 中获取数据的6种方法
一、前言
数据获取是任何 react 应用程序的核心方面。对于 React 开发人员来说,了解不同的数据获取方法以及哪些用例最适合他们很重要。
但首先,让我们了解 JavaScript Promises。
简而言之,promise 是一个 JavaScript 对象,它将在未来的某个时间产生一个值。这通常适用于异步操作(例如数据获取)。
Promises具有三种状态:
- Pending:承诺仍在进行中的地方
- Fulfilled:承诺成功解决并返回值的地方
- Rejected:承诺因错误而失败
如果一个promise被Fulfilled或Rejected,它就被解决了。Promise 有不同的方法来根据结果做不同的事情。下一节将更详细地讨论这些方法。
二、使用 Promise 方法获取 api
Fetch API 提供了一个全局的 fetch() 方法,使开发人员能够以直接的方式获取数据。在 fetch() 之前,传统方法是使用 XMLHttpRequest()。(本文不涉及此方法,因为 fetch() 已被更强大、更灵活的功能集所取代。)
fetch() 方法接受一个参数,即要请求的 URL,并返回一个promise。第二个可选参数options 是一个属性数组。fetch() 的返回值可以是 JSON 或 XML(对象数组或单个对象)。如果没有选项参数,fetch() 将始终发出 GET 请求。
第一种方法是您通常会在简单的数据获取用例中看到的方法,并且通常是浏览 API 文档时的第一个结果。
如前所述,我们从返回狗的随机图像的 API 获取数据,并将该图像呈现在屏幕上。在发出请求之前,我们将代码包装在一个带有空依赖项数组的 useEffecthook 中,以便 fetch() 方法仅在组件最初安装时运行。
useEffect(() => {fetch(URL)// syntax for handling promises.then((res) => {// check to see if response is okayif (res.ok) {// if okay, take JSON and parse to JavaScript objectreturn res.json();}throw res;})// .json() returns a promise as well.then((data) => {console.log(data);// setting response as the data statesetData(data);})// if res is not okay the res is thrown here for error.catch((err) => {console.error(`Error: ${err}`);// setting the error statesetError(err);})// regardless if promise resolves successfully or not we remove loading state.finally(() => {setLoading ( false );});}, []);
在上例中,我们调用该方法并传入 API 端点的 URL。在这个方法中,我们使用 promise 对象的方法(回想一下返回一个 promise)。
我们使用这个方法并传入一个回调函数来检查响应是否正常。如果响应正常,我们将获取返回的 JSON 数据并使用该方法将其解析为 JavaScript 对象。如果响应不正常,我们就会报错。
由于 .json() 方法也返回一个承诺,我们可以链接另一个 .then() 并传递一个函数来设置数据的状态,然后在组件的其他地方使用。在我们的示例中,外部 API 返回一个具有 url 属性的对象(它将用作 srcour 图像)。
继续通过链,下一部分是 .catch() 以安排在承诺被拒绝时调用的函数。这也返回另一个承诺,然后我们可以链接 .finally() 无论承诺是否已解决(解决或拒绝),它都会被调用。
这种 .finally() 方法使我们能够避免在 .then() 和 .catch() 中重复代码,使其成为我们示例中删除加载状态的好地方。
三、带有 Promise 方法的库 Axios
Axios 是一个流行的 HTTP 客户端库,用于高效的数据获取。它可以通过 npm 或其他包管理器轻松安装到 React 应用程序中。使用 Axios 是 Fetch API 的替代方法,如果您不介意安装外部库,它有一些优势。
第二个示例将非常接近第一个示例的代码,使用相同的 promise 方法来处理 promise 状态和响应。
在 fetch() 将 Axios 库导入我们的组件之后,我们可以使用 axios.get() 一种可以将 URL 传递到我们的外部 API 端点的方法。
这将返回一个 Promise,因此我们可以采用与 Promise 方法链接相同的方法。
useEffect(() => {axios.get(URL)// syntax for handling promises.then((res) => {console.log(res.data);// axios converts json to object for us (shortens our code)setData(res.data);})// axios takes care of error handling for us instead of checking manually.catch((err) => {console.error(`Error: ${err}`);// setting the error statesetError(err);})// regardless if promise resolves successfully or not we remove loading state.finally(() => {setLoading ( false );});}, []);
Fetch API 的代码与此 Axios 方法之间的明显区别在于,使用 Axios 我们只需要一个,因为 Axios 为我们将 .then()JSON 转换为 JavaScript 对象(缩短了我们的代码)。
另外,我们不再写条件来手动抛出错误,因为axios会为你抛出400和500范围的错误(再次缩短我们的代码)。
四、异步函数(async/await)
在此示例中,我们将放弃在前两个示例中使用的承诺链,而是引入一种更现代的方法来编写异步的、基于承诺的代码。
这种方法可以与您选择的任何抓取机制一起使用,但对于本示例,我们将坚持使用 Axios 库。
第三个示例与前一个示例类似的方式设置组件,方法是导入 Axios 库,然后使用一个空的 dependencies 数组包装用于在 useEffecta 中获取数据的代码。
在 useEffect 中,我们使用关键字 async 创建一个异步函数,然后在该函数中我们有三个独立的部分 - try、catch 和 finally。
这种 try/catch 方法用于处理 JavaScript 中的错误。try块内的代码首先被执行,如果抛出任何错误,它们将被“捕获”在块中,catch并执行内部代码。
最后,finallyblock 将始终在流通过 try/catch 之后执行。
useEffect(() => {// create async function b/c cannot use async in useEffect arg cbconst fetchData = async () => {// with async/await use the try catch block syntax for handlingtry {// using await to make async code look sync and shorten const res = await axios.get(URL);setData(res.data);} catch (err) {console.error(`Error: ${err}`);// setting the error statesetError(err);} finally {setLoading ( false );}};fetchData ();}, []);
在此示例中,try 块创建了一个名为 res(response 的缩写)的变量,该变量使用 async 关键字。这允许代码看起来同步(更短,更容易在眼睛上)。
在此示例中,axios.get(URL) 正在“等待”直到它稳定下来。如果承诺得到履行,那么我们将数据设置为状态。如果承诺被拒绝(抛出错误),它会进入 catch 块。
五、创建一个“useFetch”自定义 React Hook
第四种方法是创建我们自己的自定义 React 钩子,调用 useFetchit 可以在我们应用程序的不同组件中重复使用,并从每个组件中删除笨重的获取代码。
这个例子实际上只是采用第四个例子(使用 Axios 库和 async/await 的相同技术)并将该代码移动到它自己的自定义钩子中。
为此,我们创建了一个名为 useFetch.js 的函数。然后我们使用 Effect 将前面示例中的所有代码以及我们正在跟踪的不同状态添加到函数 useFetch 中。
最后,这个函数将返回一个包含每个状态的对象,然后在调用钩子的地方使用 useFetchaccessed。我们的 useFetchhook 还将接受一个参数,即 URL ,以允许更多的可重用性和向不同端点发出提取请求的可能性。
const useFetch = (url) => {const [data, setData] = useState(null);const [ loading , setLoading ] = useState ( true );const [error, setError] = useState(null);useEffect(() => {// create async function b/c cannot use asyc in useEffect arg cbconst fetchData = async () => {// with async/await use the try catch block syntax for handlingtry {// using await to make async code look sync and shortenconst res = await axios.get(url);setData(res.data);} catch (err) {console.error(`Error: ${err}`);// setting the error statesetError(err);} finally {setLoading ( false );}};fetchData ();}, []);return {data,loading,error,};
};
最后,我们将这个新的自定义钩子导入到将使用它的组件中,并像调用任何其他 React 钩子一样调用它。如您所见,这极大地提高了代码的可读性并缩短了我们的组件。
这种方法的最后一点是您还可以安装外部库而不是创建您自己的自定义挂钩。一个流行的库 react-fetch-hook 与我们刚刚构建的钩子具有非常相似的功能。
六、React 查询库
在 React 中获取数据的最现代和最强大的方法之一是使用 React Query 库。除了简单的数据获取之外,它还有许多功能,但是对于这个例子,我们将学习如何从同一个示例外部 API 中简单地获取数据。
安装和导入后,React Query 提供了许多自定义挂钩,可以以非常干净的方式在我们的组件中重复使用。
在此示例中,我们从中导入 QueryClient,然后使用提供程序包装我们的应用程序,并将 QueryClientProvider 实例作为属性传递给包装器。
这使我们能够在我们的应用程序中使用该库。
为了发出这个简单的 GET 请求,我们导入并使用了 useQueryhooks。与前面使用自定义挂钩的示例不同,我们传入了两个参数。
第一个必需参数是 queryKey ,用作此特定查询的参考键。
第二个必需参数是 queryFn ,它是查询将用于请求数据的函数。
我们将使用此查询函数,然后使用 Fetch API 和 promise 方法语法进行初始提取,而不是像我们之前的自定义挂钩示例中那样只传递一个简单的 URL。(这个钩子有许多其他可选参数。)
const { isLoading, error, data } = useQuery("dogData", () => fetch(URL).then((res) => res.json()));
isLoading 从这里开始,React Query 将在幕后完成所有额外的工作,在这种情况下,我们可以从这个钩子调用 destructure 、 error 和 use data in our application,尽管我们也可以访问许多其他值。
在比我们当前的 Dog Image API 示例更大的示例中,使用 React Query 的力量和优势是显而易见的。需要提及的一些附加功能包括:缓存、在后台更新“陈旧”数据以及其他与性能相关的优势。
七、Redux 工具包 RTK 查询
本文最后一种方法是使用Redux Toolkit的RTK Query进行数据采集。应用程序使用 Redux 进行状态管理是很常见的。
如果您的公司或您当前的副项目目前正在使用 Redux,一个不错的选择是使用 RTK 查询来获取数据,因为它提供了与 React 查询类似的简单性和优势。
要在存储 Redux 代码的任何地方开始使用 RTK 查询,请创建一个 rtkQueryService.js 文件来设置数据获取。
创建后,您将服务添加到您的 Redux 商店,假设您已经在使用 Redux,您将已经拥有一个包含您的应用程序的 <Provider>store 组件。
从这里开始,它与使用带有 React Query 方法的自定义钩子非常相似,您导入然后使用查询钩子并解构数据,错误然后是 Loading 可以在您的组件中使用。
const { data, error, isLoading } = useGetDogQuery();
如您所见,Redux 有很多设置,因此这可能不是我们用例的最佳方法,但如果您已经在 React 应用程序中使用 Redux 并且想要一种简单而现代的获取数据的方式,RTK 查询 可能很棒很有价值,这也提供了缓存等好处。
最后的想法
如果你已经看到了这里,那么恭喜你!这篇文章的目的就是为那些学习 React 的人介绍一些不同的数据获取方法。
在这篇文章中,我介绍了6种方法,希望这6种方法对你有用,也希望你能从中学习到一些新东西。
此外,还有其他当前的数据获取方法未在此文章中提及,我相信随着 React 生态系统的发展,其他方法将会出现。也就是说,我相信本文为理解该领域提供了坚实的基础。
相关内容拓展:(技术前沿)
近10年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。
针对这类问题,低代码把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。极大的提高了程序员的生产效率。
推荐一款程序员都应该知道的软件JNPF快速开发平台,采用业内领先的SpringBoot微服务架构、支持SpringCloud模式,完善了平台的扩增基础,满足了系统快速开发、灵活拓展、无缝集成和高性能应用等综合能力;采用前后端分离模式,前端和后端的开发人员可分工合作负责不同板块,省事又便捷。
免费体验官网:https://www.jnpfsoft.com/?csdn
还没有了解低代码这项技术可以赶紧体验学习!
相关文章:

在 React 中获取数据的6种方法
一、前言 数据获取是任何 react 应用程序的核心方面。对于 React 开发人员来说,了解不同的数据获取方法以及哪些用例最适合他们很重要。 但首先,让我们了解 JavaScript Promises。 简而言之,promise 是一个 JavaScript 对象,它将…...

Docker基础入门:常规软件安装与镜像加载原理
Docker基础入门:常规软件安装与镜像加载原理 一、Docker常规软件安装1.1、部署nginx1.2、部署tomcat1.3、部署elasticsearch1.4、如何部署kibana-->连接elasticsearch1.5、部署可视化工具 二、 镜像加载原理2.1、镜像是什么2.2、Docker镜像加速原理2.3、分层理解…...
redis初识
目录 前言: 核心全局命令 key过期实现方式 定时器实现方式 基于优先级队列/堆 redis特性 redis优点 redis单线程模型 redis单线程为什么效率这么高? 核心五种数据类型内部编码方式 前言: redis作为当前主流的内存数据库(…...

死锁的典型情况、产生的必要条件和解决方案
前言 死锁:多个线程同时被阻塞,他们中的一个或全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。 目录 前言 一、死锁的三种典型情况 (一)一个线程一把锁 (二)…...

日志搞不定?手把手教你如何使用Log4j2
系列文章目录 从零开始,手把手教你搭建Spring Boot后台工程并说明 Spring框架与SpringBoot的关联与区别 SpringBean生成流程详解 —— 由浅入深(附超精细流程图) Spring监听器用法与原理详解 Spring事务畅谈 —— 由浅入深彻底弄懂 Transactional注解 面试热点详解…...

基于Googlenet深度学习网络的交通工具种类识别matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ....................................................................................% 获…...
R语言04-R语言中的列表
概念 在R语言中,列表(List)是一种复杂的数据结构,用于存储不同类型的元素,包括向量、矩阵、数据框、函数等。列表是一种非常灵活的数据结构,可以将不同类型的数据组合在一起,类似于Python中的字…...

[Linux]进程概念
[Linux]进程概念 文章目录 [Linux]进程概念进程的定义进程和程序的关系Linux下查看进程Linux下通过系统调用获取进程标示符Linux下通过系统调用创建进程-fork函数使用 进程的定义 进程是程序的一个执行实例,是担当分配系统资源(CPU时间,内存…...
GEE/PIE遥感大数据处理与应用
随着航空、航天、近地空间等多个遥感平台的不断发展,近年来遥感技术突飞猛进。由此,遥感数据的空间、时间、光谱分辨率不断提高,数据量也大幅增长,使其越来越具有大数据特征。对于相关研究而言,遥感大数据的出现为其提…...
● 647. 回文子串 ● 516.最长回文子序列
647. 回文子串 class Solution { public:int countSubstrings(string s) {vector<vector<bool>>dp(s.size(),vector<bool>(s.size(),false));int res0;for(int is.size()-1;i>0;i--){for(int ji;j<s.size();j){if(s[i]s[j]){if(j-i<1){res;dp[i][…...

Mysql group by使用示例
文章目录 1. groupby时不能查询*2. 查询出的列必须在group by的条件列中3. group by多个字段,这些字段都有索引也会索引失效,只有group by单个字段索引才能起作用4. having条件必须跟group by相关联5. 用group by做去重6. 使用聚合函数做数量统计7. havi…...

淘宝商品详情采集接口item_get-获得淘宝商品详情(可高并发线程)
获得淘宝商品详情页面数据采集如下: taobao.item_get 公共参数 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)注册key账号接入secretString是调用密钥api_nameString是API接口名称(包括在请求地址中࿰…...
uniapp写公众号h5开发 附件上传 下载功能
一。 uni-app实现文件上传功能 目前,找到一款第三方插件 文件上传插件地址 https://ext.dcloud.net.cn/plugin?id=1015 将插件下载并导入项目中直接拿来使用,插件市场也有对改插件用法的描述。 用法: 1. 以下代码写于根目录下第一个view顶部或跟在自定义导航栏后面 // 以…...
机器学习基础09-审查分类算法(基于印第安糖尿病Pima Indians数据集)
算法审查是选择合适的机器学习算法的主要方法之一。审查算法前并 不知道哪个算法对问题最有效,必须设计一定的实验进行验证,以找到对问题最有效的算法。本章将学习通过 scikit-learn来审查六种机器学习的分类算法,通过比较算法评估矩阵的结果…...
C++ sort与优先队列排序的区别
int main() {vector<int> data{3, 1, 2};cout << "从小到大排序" << endl;sort(data.begin(), data.end(), std::less<int>());printContainer(data);auto cmp1 [](int x, int y) { return x < y; };sort(data.begin(), data.end(), cmp…...

【Rust】Rust学习 第十九章高级特征
现在我们已经学习了 Rust 编程语言中最常用的部分。在第二十章开始另一个新项目之前,让我们聊聊一些总有一天你会遇上的部分内容。你可以将本章作为不经意间遇到未知的内容时的参考。本章将要学习的功能在一些非常特定的场景下很有用处。虽然很少会碰到它们…...
C++ 纯虚函数和虚函数的区别
在 C 中,虚函数(Virtual Function)和纯虚函数(Pure Virtual Function)都是用于实现多态性的机制,但它们之间有一些关键的不同。 虚函数(Virtual Function) 定义:在基类…...

Go中的有限状态机FSM的详细介绍 _
1、FSM简介 1.1 有限状态机的定义 有限状态机(Finite State Machine,FSM)是一种数学模型,用于描述系统在不同状态下的行为和转移条件。 状态机有三个组成部分:状态(State)、事件(…...

Python入门教程 | Python3 基本数据类型
赋值 Python 中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存中对象的类型。 等号(ÿ…...
STM32移植u8g2玩转oled 用软件iic实现驱动oled
移植u8g2到stm int fputc(int ch,FILE *f) {ITM_SendChar(ch);return (ch); }void delay_us(uint32_t time) {uint32_t i8*time;while(i--); }uint8_t STM32_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {//printf("%s:msg %d,arg_int …...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...