(译) 如何使用 React hooks 获取 api 接口数据

本文详细介绍了如何使用React Hooks获取和管理API数据,包括如何使用useState和useEffect来处理数据加载、错误处理和表单数据。通过自定义Hook实现数据获取的复用,以及使用Reducer Hook整合状态管理,避免无效状态。还讨论了在Effect Hook中如何处理数据请求的取消,以防止组件卸载后的状态设置问题。
摘要由CSDN通过智能技术生成

640?wx_fmt=gif

点击上方“蓝字”带你每天阅读全栈前端精选好文

640

原文地址:robinwieruch

在本教程中,我想向你展示如何使用 state 和 effect 钩子在React中获取数据。 你还将实现自定义的 hooks 来获取数据,可以在应用程序的任何位置重用,也可以作为独立节点包在npm上发布。

如果你对 React 的新功能一无所知,可以查看 React hooks 的相关 api 介绍。如果你想查看完整的如何使用 React Hooks 获取数据的项目代码,可以查看 github 的仓库

如果你只是想用 React Hooks 进行数据的获取,直接 npm i use-data-api并根据文档进行操作。如果你使用他,别忘记给我个star 哦~

注意:将来,React Hooks 不适用于 React 中获取数据。一个名为Suspense的功能将负责它。以下演练是了解React中有关 state 和 Effect hooks 的更多信息的好方法。

使用 React hooks 获取数据

如果您不熟悉React中的数据提取,请查看我在React文章中提取的大量数据。它将引导您完成使用React类组件的数据获取,如何使用Render Prop 组件和高阶组件来复用这些数据,以及它如何处理错误以及 loading 的。

 1  import React, { useState } from 'react';
 2
 3  function App() {
 4    const [data, setData] = useState({ hits: [] });
 5
 6    return (
 7      <ul>
 8        {data.hits.map(item => (
 9          <li key={item.objectID}>
10            <a href={item.url}>{item.title}</a>
11          </li>
12        ))}
13      </ul>
14    );
15  }
16
17  export default App;

App 组件显示了一个项目列表(hits=Hacker News 文章)。状态和状态更新函数来自useState 的 hook。他是来负责管理我们这个 data 的状态的。userState 中的第一个值是data 的初始值。其实就是个解构赋值。

这里我们使用 axios 来获取数据,当然,你也可以使用别的开源库。

 1import React, { useState, useEffect } from 'react';
 2import axios from 'axios';
 3
 4function App() {
 5  const [data, setData] = useState({ hits: [] });
 6
 7  useEffect(async () => {
 8    const result = await axios(
 9      'https://hn.algolia.com/api/v1/search?query=redux',
10    );
11
12    setData(result.data);
13  });
14
15  return (
16    <ul>
17      {data.hits.map(item => (
18        <li key={item.objectID}>
19          <a href={item.url}>{item.title}</a>
20        </li>
21      ))}
22    </ul>
23  );
24}
25
26export default App;

这里我们使用 useEffect 的 effect hook 来获取数据。并且使用 useState 中的 setData 来更新组件状态。

但是如上代码运行的时候,你会发现一个特别烦人的循环问题。effect hook 的触发不仅仅是在组件第一次加载的时候,还有在每一次更新的时候也会触发。由于我们在获取到数据后就进行设置了组件状态,然后又触发了 effect hook。所以就会出现死循环。很显然,这是一个 bug!我们只想在组件第一次加载的时候获取数据 ,这也就是为什么你可以提供一个空数组作为 useEffect 的第二个参数以避免在组件更新的时候也触发它。当然,这样的话,也就是在组件加载的时候触发。

 1  import React, { useState, useEffect } from 'react';
 2  import axios from 'axios';
 3
 4  function App() {
 5    const [data, setData] = useState({ hits: [] });
 6
 7    useEffect(async () => {
 8      const result = await axios(
 9        'https://hn.algolia.com/api/v1/search?query=redux',
10      );
11
12      setData(result.data);
13    }, []);
14
15    return (
16      <ul>
17        {data.hits.map(item => (
18          <li key={item.objectID}>
19            <a href={item.url}>{item.title}</a>
20          </li>
21        ))}
22      </ul>
23    );
24  }
25
26  export default App;

第二个参数可以用来定义 hook 所依赖的所有变量(在这个数组中),如果其中一个变量发生变化,则就会触发这个 hook 的运行。如果传递的是一个空数组,则仅仅在第一次加载的时候运行。

是不是感觉 ,干了shouldComponentUpdate 的事情

这里还有一个陷阱。在这个代码里面,我们使用 async/await 去获取第三方的 API 的接口数据,根据文档,每一个 async 都会返回一个 promise:async 函数声明定义了一个异步函数,它返回一个 AsyncFunction 对象。异步函数是通过事件循环异步操作的函数,使用隐式的 Promise 返回结果然而,effect hook 不应该返回任何内容,或者清除功能。这也就是为啥你看到了这个警告:07:41:22.910 index.js:1452 Warning: useEffect function must return a cleanup function or nothing. Promises and useEffect(async () => …) are not supported, but you can call an async function inside an effect.. ``

这就是为什么我们不能在useEffect中使用 async的原因。但是我们可以通过如下方法解决:

 1  import React, { useState, useEffect } from 'react';
 2  import axios from 'axios';
 3
 4  function App() {
 5    const [data, setData] = useState({ hits: [] });
 6
 7    useEffect(() => {
 8      const fetchData = async () => {
 9        const result = await axios(
10          'https://hn.algolia.com/api/v1/search?query=redux',
11        );
12
13        setData(result.data);
14      };
15
16      fetchData();
17    }, []);
18
19    return (
20      <ul>
21        {data.hits.map(item => (
22          <li key={item.objectID}>
23            <a h
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值