在 React 中获取数据:快速指南
可以通过多种方式从 API(从外部源或应用程序后端)获取数据。
在本快速指南中,我将向您展示如何通过使用 4 种不同的模式向 REST API 发出 HTTP 请求来获取 React 应用程序中的数据。
在开始之前,让我们先回顾一下 REST API 是什么:
什么是 REST API?
REST API(也称为RESTful API )是一种符合 REST 架构风格约束并允许与 RESTful Web 服务交互的应用程序编程接口(API或Web API )。REST 代表“ REST表示状态转移”。
在本指南中,我们将使用Github REST API,其示例响应如下所示:
{
"login": "jideabdqudus",
"id": 45945474,
"node_id": "MDQ6VXNlcjQ1OTQ1NDc0",
"avatar_url": "https://avatars.githubusercontent.com/u/45945474?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/jideabdqudus",
"html_url": "https://github.com/jideabdqudus",
"followers_url": "https://api.github.com/users/jideabdqudus/followers",
"following_url": "https://api.github.com/users/jideabdqudus/following{/other_user}",
"gists_url": "https://api.github.com/users/jideabdqudus/gists{/gist_id}",
"starred_url": "https://api.github.com/users/jideabdqudus/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/jideabdqudus/subscriptions",
"organizations_url": "https://api.github.com/users/jideabdqudus/orgs",
"repos_url": "https://api.github.com/users/jideabdqudus/repos",
"events_url": "https://api.github.com/users/jideabdqudus/events{/privacy}",
"received_events_url": "https://api.github.com/users/jideabdqudus/received_events",
"type": "User",
"site_admin": false,
"name": "Jide Abdul-Qudus.",
"company": null,
"blog": "www.abdulqudus.com",
"location": "Lagos, Nigeria.",
"email": null,
"hireable": true,
"bio": "Software Engineer.",
"twitter_username": null,
"public_repos": 57,
"public_gists": 0,
"followers": 12,
"following": 0,
"created_at": "2018-12-17T15:57:35Z",
"updated_at": "2021-04-06T20:48:07Z"
}
每当向此(api.github.com/users/jideabdqudus)端点发出 GET 请求时,它都会返回此 Javascript 对象作为其响应,我们可以决定在我们的应用程序中使用此数据。
使用 Fetch API 获取数据
Fetch API 是一种内置的 JavaScript 方法,用于从服务器或 API 端点获取资源。它是大多数现代浏览器内置于 window 对象 ( window.fetch
) 中的工具,使我们能够使用 JavaScript Promise 轻松发出 HTTP 请求。
要使用 fetch 发出一个简单的 GET 请求,我们只需要包含 URL 端点(这是一个强制参数)。它会返回一个指向请求响应的 Promise。我们希望在 React 组件挂载后发出此请求,因此对于基于函数式的组件,我们会使用名为useEffect的 Hook ,而对于基于类的组件,我们会使用名为componentDidMount 的Hook 。
import React, { useState, useEffect } from "react";
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://api.github.com/users/jideabdqudus")
.then((response) => {
if (response.ok) {
return response.json();
}
throw response;
})
.then((data) => {
setData(data);
})
.catch((error) => {
console.error("Error fetching data: ", error);
setError(error);
})
.finally(() => {
setLoading(false);
});
}, []);
if (loading) return "Loading...";
if (error) return "Error!";
return (
<div style={{ textAlign: "center" }}>
<img src={data.avatar_url} alt="Avatar" height="100" />
<p>Name: {data.name}</p>
<p>Bio: {data.bio}</p>
<p>Username: {data.login}</p>
<p>Location: {data.location}</p>
<p>Public Repos: {data.public_repos}</p>
</div>
);
}
在上面的代码中,我们创建了一个非常简单的功能组件,该组件在安装后会发出获取请求,并以数据状态将响应发送回给我们。
在 useEffect 中,我们在 fetch 函数内部声明了 API 端点,.then()
回调函数用于检查响应是否正常(response.ok
)。如果响应正常,我们将以 JSON 数据的形式回调响应。
如果响应不正常,我们会假设请求过程中出现了错误。为了处理错误,我们使用 fetch 函数,将response
其抛出为一个错误,并由回调函数处理catch
。
在我们的示例中,我们使用 setError 将错误数据放入状态中。如果发生错误,我们将返回文本“Error!”。
回调函数.finally()
是一个函数,无论我们的 Promise 是否成功解析,都会被调用。在这个函数中,我们将 Loading 设置为 false,这样我们就看不到loading
文本了。
相反,如果请求成功,我们会在页面上看到我们的数据,如果请求失败,我们会发现请求过程中出现了错误。
如何使用 Axios 在 React 中获取数据
第二种模式是利用 Axios。Axios 是一个易于使用的基于 Promise 的 HTTP 客户端,适用于浏览器和 Node.js。使用 Axios,我们可以拦截和取消请求,它还内置了一项功能,可以在客户端防止跨站请求伪造。
Axios 是一个 React/Javascript 库,因此为了在我们的应用程序中使用它,我们需要先安装它。
npm install axios or yarn add axios
之后,我们将它导入到要使用的组件顶部。使用 Axios 发起 HTTP 请求非常简单,而且它是 React 中最流行的数据获取方式之一。我们将把之前的 Fetch 示例转换为 axios 请求。
import React, { useState, useEffect } from "react";
import axios from "axios";
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
axios("https://api.github.com/users/jideabdqudus")
.then((response) => {
setData(response.data);
})
.catch((error) => {
console.error("Error fetching data: ", error);
setError(error);
})
.finally(() => {
setLoading(false);
});
}, []);
if (loading) return "Loading...";
if (error) return "Error!";
return (
<div style={{ textAlign: "center" }}>
<img src={data.avatar_url} alt="Avatar" height="100" />
<p>Name: {data.name}</p>
<p>Bio: {data.bio}</p>
<p>Username: {data.login}</p>
<p>Location: {data.location}</p>
<p>Public Repos: {data.public_repos}</p>
</div>
);
}
Axios 让我们能够使用与 fetch 完全相同的承诺语法 - 但不是使用我们的第一个回调来手动确定响应是否正常并抛出错误,Axios 会为我们处理这个问题。
async / await
使用语法在 React 中获取数据
在 ES7 中,可以使用 async / await 语法来解决 Promise。Async/await 是一种在 JavaScript 中编写异步代码的相对较新的方法。
这样做的好处是,它使我们能够删除我们的.then()
、.catch()
和.finally()
回调、承诺,并简单地取回我们的异步解析数据,就好像我们编写完全没有承诺的同步代码一样。
为什么async/await
?简单来说,async/await 允许我们以同步的方式编写异步代码。关于异步函数,你需要知道的一件事是:它们总是返回一个 Promise。
我们必须意识到,当我们使用useEffect
效果函数(第一个参数)时,不能将其变成async
函数。
要创建一个async
函数,我们需要做的就是async
在函数定义之前添加关键字,我们将前面的示例转换为 async/await 语法:
import React, { useState, useEffect } from "react";
import axios from "axios";
export default function App() {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
getData();
}, []);
async function getData() {
await axios("https://api.github.com/users/jideabdqudus")
.then((response) => {
setData(response.data);
})
.catch((error) => {
console.error("Error fetching data: ", error);
setError(error);
})
.finally(() => {
setLoading(false);
});
}
if (loading) return "Loading...";
if (error) return "Error!";
return (
<div style={{ textAlign: "center" }}>
<img src={data.avatar_url} alt="Avatar" height="100" />
<p>Name: {data.name}</p>
<p>Bio: {data.bio}</p>
<p>Username: {data.login}</p>
<p>Location: {data.location}</p>
<p>Public Repos: {data.public_repos}</p>
</div>
);
}
总而言之,async/await
这是一种编写异步 JavaScript 代码的更简洁的语法。它增强了代码的可读性和流畅性。
使用时需注意的事项async/await
:
-
异步函数返回一个承诺。
-
Await 只能在异步块内使用。
-
Await 等待直到函数(“promise”)解决或拒绝。
如何使用自定义 React Hook (useFetch) 在 React 中获取数据
随着时间的推移,您可能会意识到,在每个想要获取数据的组件中不断编写 useEffect 钩子及其所有样板会变得有点乏味和耗时。
为了减少重复使用的代码,我们可以使用自定义钩子作为特殊的抽象,我们可以从第三方库中自己编写它(就像我们在这里使用库一样react-fetch-hook
)。
useFetch 是一个同构的 fetch hook。这意味着它可以与 SSR(服务器端渲染)配合使用。
自定义钩子可以发出 HTTP 请求,让我们的组件更加简洁。我们只需要在组件顶部调用钩子即可。
import React from "react";
import useFetch from "react-fetch-hook"
export default function App() {
const { isLoading, error, data } = useFetch("https://api.github.com/users/jideabdqudus");
if (isLoading) return "Loading...";
if (error) return "Error!";
return (
<div style={{ textAlign: "center" }}>
<img src={data.avatar_url} alt="Avatar" height="100" />
<p>Name: {data.name}</p>
<p>Bio: {data.bio}</p>
<p>Username: {data.login}</p>
<p>Location: {data.location}</p>
<p>Public Repos: {data.public_repos}</p>
</div>
);
}
结论
上面显示的 4 种不同模式是使用 API 的好方法,但 fetch 主要用于构建相对较小的应用程序,而 Axios/useFetch 主要用于构建大型应用程序以达到可扩展性的目的。
我希望您喜欢阅读本指南,我很乐意回答您在下面留下的任何评论或问题!
在我的网站上查看更多文章:blog.abdulqudus.com
文章来源:https://dev.to/jideabdqudus/fetching-data-in-react-quick-guide-4fba