如何在客户端不从API获取数据时获取组件
在构建React应用程序时,通常从API获取数据并在组件中显示它。然而,可能会出现数据在首次渲染组件时尚未可用的情况。在这种情况下,重要的是处理数据尚未提取的情况,并向用户显示加载或错误消息。
开发人员经常遇到的一个常见问题是如何处理API调用返回无数据的情况,也称为空响应。在这种情况下,需要返回一个组件,通知用户没有可用的数据。
useState Hook: useState是React Hook,可帮助你向组件添加状态变量。第一个元素是初始状态,第二个是用于更新状态的函数。
语法:
const [state, setState] = useState(initialstate)
useEffect Hook: useEffect是React的一个Hook,它允许您将组件与外部系统同步。它允许您执行副作用。副作用的示例包括数据获取、设置订阅和在React组件中手动更改DOM。
语法:
useEffect(setup, dependencies?)
方法: 在React.js中,您可以返回一个组件,当数据尚未从API获取时,该组件会显示加载消息或回退组件。这可以通过根据数据的状态进行条件渲染来实现。
在下面的示例中,我们有一个组件从API获取数据并在列表中显示它。但是,如果在组件首次渲染时数据尚不可用,则会抛出错误,因为它正在尝试映射一个未定义的状态变量。
运行程序的步骤:
步骤1: 运行以下命令初始化一个新的React项目:
npx create-react-app my-app
步骤2: 进入新创建的项目目录:
cd my-app
步骤3: 要启动开发服务器,请运行以下命令:
npm start
项目结构:
示例1:
import React, { useState, useEffect } from 'react';
const Example = () => {
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://api...com/data')
.then(res => res.json())
.then(data => setResponse(data))
.catch(error => setError(error));
}, []);
if (error) {
return <div>An error occurred: {error.message}</div>;
} else if (!response) {
return <div>Loading...</div>;
} else {
return <div>
Response from API:
{JSON.stringify(response)}
</div>;
}
};
export default Example;
输出:
在这个示例中, useEffect **被用来调用一个API并将结果 **response 或 error 保存在组件的状态中。然后组件根据当前的状态返回一个消息(可能是一个错误消息、一个加载消息或来自API的响应)。
示例2: 在这个示例中,我们将使用一个名为spoonacular API的实时API构建一个小型应用程序,用于显示包括菜谱名称和图片的菜谱列表。它是免费使用的。您只需要注册一个 免费账户 ,然后在API控制台的个人资料部分生成一个 唯一的API密钥 。一旦您获得了API密钥,您必须将它放在每个请求的请求URL中,就像这样:“ ?apiKey=YOUR-API-KEY ”。
先决条件:
- 通过LTS版本下载Node包。
- spoonacular API密钥
App.js
import React, { useState, useEffect } from "react";
const App = () => {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
console.log(data);
useEffect(() => {
fetch(
"https://api.spoonacular.com/recipes/complexSearch?apiKey=YOUR_API_KEY"
)
.then((res) => res.json())
.then((data) => setData(data))
.catch((error) => setError(error));
}, []);
if (error) {
return <div>An error occurred: {error.message}</div>;
} else if (!data) {
return <h2>Loading...</h2>;
} else {
return (
<div>
<h1>Recipes</h1>
<ul>
{data.results.map((item) => (
<li key={item.id}>
<p>{item.title}</p>
<img src={item.image} alt="img" />
</li>
))}
</ul>
</div>
);
}
};
export default App;
逐步解释:
- 从React库中导入所需的依赖项。 useState 和 useEffect 都在React中引入了用于管理组件状态和副作用的概念。
- 定义一个无状态函数组件,其名称为 App 。它使用 useState 两次创建两个状态变量: data 和 error 。 data 和 error 都最初设置为null。分别使用 setData 和 setError 函数来更新 data 和 error 的值。
- 使用 useEffect 钩子在组件挂载时从API获取数据。
- 用你自己的免费唯一的 API key 替换 YOUR-API-KEY ,此键在注册后生成。这里,我们使用 Search Recipes API来获取不同的食谱。
- fetch请求返回一个Promise,它要么用API数据解析,要么用 error 拒绝。如果Promise解析, setData 被调用以更新 data 状态。如果Promise拒绝, setError 被调用以更新 error 状态。对于 useEffect 的第二个参数('[]’),是一个依赖项数组,它表示该钩子所依赖的其他状态变量。通过提供一个空数组,我们告诉React只在组件初次挂载时调用 useEffect 一次。
- 添加条件语句来检查 error 和 data 的当前状态。如果 error 为真,它返回一个显示错误信息的组件。如果 data 为假(即 null ),它返回一个显示加载信息的组件。如果 error 和 data 都为假,它返回一个以列表形式显示获取到的数据的组件。
- 最后,将 App 组件作为默认导出从本模块导出。
控制台输出: 在控制台上,JSON格式的数据如下所示:
屏幕输出: 下面的输出显示“ 正在加载… ”组件,直到数据被获取并显示在屏幕上。
为了处理任何错误并向用户显示数据获取出现问题的消息,我们使用了useState hook和条件渲染的组合。如果API无法返回数据,它将返回一个显示错误消息的组件,如下所示: