app.vue里使用data_[译]使用React Hooks请求数据

6751f6e4b6ad8331d06b773ac48cca2e.png

[译]使用React Hooks请求数据

原文:How to fetch data with React Hooks?

在这篇文章里,我将演示一下,如果通过使用 useState useEffect 等hooks,在 React Hook里请求数据。我们将使用 Hacker News API 来获取最新流行的技术文章。我们将实现一个获取异步数据的自定义hook,能够在我们APP里多个地方进行复用,或者作为单独的包发布到npm上。

如果你还不了解 React Hooks,你可以通过我的 React Hooks 简介 了解下。本文完整的demo代码,在这个 github仓库 。

注意:在将来,React Hooks的用处,不是请求数据。新的 Suspense 特性,将用来请求数据。本文主要是展示我们能用hooks做些什么,来加深我们对hooks的理解。

在hooks里请求数据

如果你还不了解怎么在react里请求数据,建议先看看我的 可扩展的数据请求这篇文章,它会介绍在react class组件里,怎么进行数据请求,包括怎么通过 Render Prop Component 和 高阶组件HOC 封装可服用的数据请求逻辑,以及怎样进行 加载中和错误 的状态展示。在本文里,我将展示如果在react 函数组件 里使用 hooks 来达到同样的效果。

import React, {
     useState } from 'react';

function App() {
    
  const [data, setData] = useState({
     hits: [] });

  return (
    <ul>
      {
    data.hits.map(item => (
        <li key={
    item.objectID}>
          <a href={
    item.url}>{
    item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;

我们demo里会展示一个hacker news的文章列表。我们使用 useState 来维护APP的state以及提供更新state的操作。state的默认值是一个空的数组。

我将使用 axios 来处理数据请求,当然你也可以使用自己习惯的其他库,或者使用浏览器原生的 fetch 方法。下面我们看下加上 useEffect 来请求数据之后的代码:

import React, {
     useState, useEffect } from 'react';
import axios from 'axios';

function App() {
    
  const [data, setData] = useState({
     hits: [] });

  useEffect(async () => {
    
    const result = await axios(
      'http://hn.algolia.com/api/v1/search?query=redux',
    );

    setData(result.data);
  });

  return (
    <ul>
      {
    data.hits.map(item => (
        <li key={
    item.objectID}>
          <a href={
    item.url}>{
    item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;

useEffect 里,我们使用axios请求到数据之后,调用 useState 返回的 setData 方法,将新的数据更新到state上,从而触发组件重新render。异步函数我们使用 async/await 的语法,来简化代码。

然而,当你运行上面的代码,你会进行死循环。上面的 useEffect 函数,在组件初次挂载和每次更新的时候,都会执行;在 useEffect 函数里,我们在请求到数据之后,更新了组件的state,导致组件重新渲染,组件渲染之后,又会调用 useEffect 函数。结果就是,组件一直在请求数据,刷新,请求数据,刷新……这当然是一个必须要解决掉的bug。我们只希望在组件初次挂载的时候,请求数据。下面,我们将给 useEffect 传第二个空数组的参数,来实现这个效果:只在组件mount的时候,调用 useEffect 函数。

import React, {
     useState, useEffect } from 'react';
import axios from 'axios';

function App() {
    
  const [data, setData] = useState({
     hits: [] });

  useEffect(async () => {
    
    const result = await axios(
      'http://hn.algolia.com/api/v1/search?query=redux',
    );

    setData(result.data);
  }, []);

  return (
    <ul>
      {
    data.hits.map(item => (
        <li key={
    item.objectID}>
          <a href={
    item.url}>{
    item.title}</a>
        </li>
      ))}
    </ul>
  );
}

export default App;

useEffect 的第二个数组参数,用来定义该hook依赖的所有变量。依赖项中只要有一个改变,就会重新调用 useEffect 。如果依赖项是空的数组,表明我们的hook不依赖任何变量,因此,该hook只会在组件初次mount的时候执行。

上面的代码还有一个问题。我们使用了 async/await 来处理异步操作,根据规范,async 函数会返回一个隐式的 Promise: " The async function declaration defines an asynchronous function, which returns an AsyncFunction object. An asynchronous function is a function which operates asynchronously via the event loop, using an implicit Promise to return its result. " 。然而, effect hook 要么什么都不返回,要么返回一个清理函数。因此,运行上面的代码,你会在 console 里看到这样的警告:Warning: useEffect function must return a cleanup function

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值