使用reacts useeffect挂钩来获取数据并定期刷新该数据

本文介绍如何在React应用中使用useEffect钩子从API获取数据,并实现数据的定期刷新。通过示例代码解释了如何避免无限循环获取以及设置State来更新DOM。
摘要由CSDN通过智能技术生成

React开发 (React Development)

我们将学到什么 (What We Will Learn)

Although React’s useEffect hook allows you to do many things, In this tutorial we will walk through how to use use the useEffect hook specifically to fetch data from an API, and refresh that data periodically.

尽管React的useEffect钩子允许您做很多事情 ,但是在本教程中,我们将逐步介绍如何使用useEffect钩子专门从API提取数据,并定期刷新该数据。

You can use whatever API you prefer but we will be using the fake API https://jsonplaceholder.typicode.com/ to fetch posts.

您可以使用任何喜欢的API,但我们将使用伪造的API https://jsonplaceholder.typicode.com/来获取帖子。

https://jsonplaceholder.typicode.com/posts

使用效果 (UseEffect)

By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.

通过使用这个Hook,您可以告诉React您的组件在渲染后需要做一些事情。 React会记住您传递的函数(我们将其称为“效果”),并在执行DOM更新后稍后调用它。

Something important to notice in the statement above is that the useEffect hook runs after the DOM updates. Therefore it will not block the render process.

在上面的语句中需要注意的重要一点是,useEffect挂钩在DOM更新之后运行 。 因此,它不会阻止渲染过程。

Something else important, especially for fetching data from an API is,

还有其他一些重要的事情,尤其是对于从API提取数据而言,

By default, it runs both after the first render and after every update.

默认情况下,它在第一次渲染 之后 每次update之后都运行

This means that if we are not careful, after we get data and set State, causing a DOM update, it will fetch the data again and again and again…

这意味着如果我们不小心,在获取数据并设置State之后 ,导致DOM更新,它将一次又一次地获取数据…

We will cover how to avoid this infinite loop of fetching but also how to have it fetch periodically so that our data “refreshes” if new data is added.

我们将介绍如何避免这种无限的获取循环,以及如何定期获取数据,以便在添加新数据时“刷新”我们的数据。

让我们开始吧 (Let’s Get Started)

I will be using Visual Studio Code. You can certainly use whatever code editor you desire.

我将使用Visual Studio Code。 您当然可以使用所需的任何代码编辑器。

最初设定 (Initial Setup)

  1. Create a directory in which to place you application.

    创建用于放置应用程序的目录。
  2. Start VS Code and open the folder you just created.

    启动VS Code并打开您刚刚创建的文件夹。
  3. Open a Terminal window and enter this code to bootstrap our React app.

    打开一个终端窗口并输入以下代码以引导我们的React应用程序。
npx create-react-app fetch-with-useeffect

Next we need to change in to this directory and run npm start to start the development server to verify it is running our React app. By default this will be on localhost port 3000.

接下来,我们需要切换到该目录并运行npm start来启动开发服务器,以验证它是否正在运行我们的React应用。 默认情况下,它将位于本地主机端口3000上。

4. After your application has been bootstrapped type the following in the Terminal.

4.启动应用程序后,在终端中键入以下内容。

cd fetch-with-useeffect
npm start

You should see something similar to the image below.

您应该看到类似于下图的内容。

Image for post
Basic React Application
基本React应用

We will be using Axios to fetch our data. If you prefer you can use fetch or whatever you desire.

我们将使用Axios来获取数据。 如果您愿意,可以使用访存或任何您想要的东西。

5. Use CTRL +C to stop the development server and close the browser tab.

5.使用CTRL + C停止开发服务器并关闭浏览器选项卡。

6. Type the following in the Terminal window to install Axios.

6.在“终端”窗口中键入以下内容以安装Axios。

npm install axios

7. Open App.js and replace the default code with the code below. Notice the import of the useEffect hook, along with useState and the import of axios.

7.打开App.js并将默认代码替换为以下代码。 注意useEffect挂钩的导入 ,以及useState和axios的导入。

import React,{useEffect,useState} from 'react'import axios from 'axios'
import './App.css'const App=()=> {return (
<div>
<h1>useEffect</h1>
</div>
);
}export default App;

8. Save and restart the development server with,

8.保存并重新启动开发服务器,

npm start

You should just see only the word “useEffect” in the browser.

您应该只在浏览器中看到单词“ useEffect ”。

使用UseEffect (Working With UseEffect)

Now we are ready to use useEffect!

现在我们可以使用useEffect了!

The useEffect hook has this basic syntax.

useEffect挂钩具有此基本语法。

useEffect(()=>{// Effect goes here  
})

The useEffect hook needs to be placed in the body of the functional component in which it is used.

useEffect挂钩需要放置在使用它的功能组件的主体中。

We will fetch our posts in a javascript function named getPosts. This function will be called from the useEffect hook, which will reside in the body of the functional App component.

我们将在名为getPosts的javascript函数中获取帖子。 该函数将从useEffect挂钩中调用,该挂钩将驻留在功能性App组件的主体中。

The result of getPosts, the posts themselves, will be shown in the console initially but eventually stored in State using the useState hook.

getPosts的结果,即帖子本身,将最初在控制台中显示,但最终使用useState挂钩存储在State中。

Let’s write the function that will get the posts, getPosts, and call that function from the useEffect hook.

让我们编写将获取帖子,getPosts并从useEffect挂钩调用该函数的函数。

1. Modify your App.js like this. Observe the function getPosts and the call to the function in useEffect.

1.像这样修改您的App.js。 观察函数getPosts和useEffect中的函数调用。

import React,{useEffect,useState} from 'react'
import axios from 'axios'
import './App.css'const getPosts = async () => {
try {
const userPosts = await axios.get("https://jsonplaceholder.typicode.com/posts")
console.log(userPosts.data);
} catch (err) {
console.error(err.message);
}
};
const App=()=> {useEffect(()=>{
getPosts()
})return (
<div>
<h1>useEffect</h1>
</div>
);
}export default App;

2. Save and open your dev tools to the console. You should see a list of posts.

2.保存并打开您的开发工具到控制台。 您应该看到帖子列表。

Image for post
https://jsonplaceholder.typicode.com/posts https://jsonplaceholder.typicode.com/posts获得的帖子

Notice that each post has an id and a title.

请注意,每个帖子都有一个ID和一个标题。

We want to store these posts in State, in an array called posts, and display the posts on the screen.

我们希望将这些帖子存储在State中,称为帖子数组,并在屏幕上显示这些帖子。

We will be adding a useState hook, initialized to an empty array.

我们将添加一个useState挂钩,并将其初始化为一个空数组。

const [posts, setPosts]=useState([])

const [posts,setPosts] = useState([])

The array posts will store the array of posts returned from the GET call and setPosts is the setter method to set the value of posts.

数组帖子将存储从GET调用返回的帖子数组,而setPosts是用于设置帖子值的setter方法。

We will then map over the posts displaying the post title on the screen and use the post id as the key.

然后,我们将映射到在屏幕上显示帖子标题的帖子,并使用帖子ID作为键。

Important: As previously mentioned, useEffect is run after a DOM update. If we then change State in getPosts, which causes a DOM update, posts are fetched again. When this happens, State is set again, ad infinitum. This was not a problem when we used console.log() as State was not changed.

重要说明: 如前所述,useEffect在DOM更新后运行。 如果然后更改getPosts中的State(导致DOM更新),则会再次获取帖子。 发生这种情况时,状态将无限地重新设置。 当我们使用console.log()时,因为状态未更改,所以这不是问题。

The way to ensure useEffect is run only once is to use an empty dependency array.

确保useEffect仅运行一次的方法是使用一个空的依赖项数组。

We will not focus on all the uses of the dependency array in this article except to note an empty one keeps useEffect from running after every render. More on the dependency array can be found here.

我们不会在本文中集中讨论依赖项数组的所有用法,只是要注意,如果有一个空的值,则会阻止useEffect在每次渲染后都运行。 有关依赖项数组的更多信息,请参见此处

The new syntax for useEffect is below. Notice the empty array.

useEffect的新语法如下。 注意空数组。

useEffect(() =>{// Effect goes here  }, [])

Here is the result, from the network section of your dev tools if an empty dependency array is not used. It is not apparent from the image that the GET’s are being performed continuously.

这是从开发工具的网络部分获得的结果,如果不使用空的依赖项数组 从图像中看不出正在连续执行GET。

Image for post
Infinite loop of GET requests when not using an empty dependency array.
不使用空的依赖项数组时,GET请求的无限循环。

显示帖子 (Displaying The Posts)

In the code to follow, we add useState, pass this to our getPosts function so it can set the State of posts to the userPosts.data.

在下面的代码中,我们添加useState,并将其传递给我们的getPosts函数,以便它可以将发布的状态设置为userPosts.data。

Note that you could include the getPosts function in the functional App component body instead. This would keep you from having to pass setPosts to the function.

请注意,您可以将getPosts函数包含在功能性App组件主体中。 这将使您不必将setPosts传递给函数。

In the return statement of App.js, we map over the posts array.

在App.js的return语句中,我们映射到posts数组。

  1. Make these changes to App.js, noting the items in bold.

    对App.js进行这些更改,并以粗体显示项目。
import React,{useEffect,useState} from 'react'
import axios from 'axios'
import './App.css'const getPosts = async (setPosts) => {
try {const userPosts = await axios.get("https://jsonplaceholder.typicode.com/posts")setPosts(userPosts.data); // set State
} catch (err) {
console.error(err.message);
}
};const App=()=> { const [posts, setPosts]=useState([])
useEffect(()=>{
getPosts(setPosts)},[]) // includes empty dependency arrayreturn (
<div>
<h1>useEffect</h1>
<ul> {posts.map(post=>(
<li key={post.id}>{post.title}</li>
))}

</ul>
</div>
);
}export default App;

2. Save and observe your application in the browser. It should look at follows,

2.保存并在浏览器中观察您的应用程序。 应该看如下,

Image for post
Posts returned from our App component
从我们的App组件返回的帖子

刷新帖子 (Refreshing The Posts)

Although our list of posts will not change as none are being added, in a real application, where other users may be adding posts, you may want to refresh the list posts on a periodic basis of your choosing.

尽管我们的帖子列表不会更改,因为不会添加任何帖子,但是在其他用户可能正在添加帖子的真实应用程序中,您可能希望定期选择刷新列表帖子。

We will use setInterval to update our list of posts every 10 seconds. Since no actual new posts will be displayed (typicode is a fake API), we will have to use our dev tools network section to observe the GET call every 10 seconds.

我们将使用setInterval每10秒更新一次帖子列表。 由于将不会显示实际的新帖子( typicode是伪造的API),因此我们将不得不使用开发工具网络部分每10秒观察一次GET调用。

We will also be adding a clearInterval. This would be important in a larger application so that the interval is cleared when the user navigates to another page.

我们还将添加一个clearInterval。 这在较大的应用程序中非常重要,因此当用户导航到另一个页面时,间隔将被清除。

To accomplish the refresh, modify the useEffect as follows,

要完成刷新,请如下修改useEffect,

useEffect(()=>{ getPosts(setPosts)    const interval=setInterval(()=>{ getPosts(setPosts)
},10000) return()=>clearInterval(interval)},[])

We initially get the posts and then every 10 seconds call getPosts again.

我们最初获取帖子,然后每10秒钟再次调用getPosts。

Using your developer tools, examine network, and you will see a GET every 10 seconds.

使用开发人员工具检查网络,您将每10秒看到一次GET。

Image for post
Initial GET and one every 10 seconds
初始GET,每10秒一次

结论 (Conclusion)

In summary we have seen one use of useEffect, fetching data. We also learned that without the empty dependency array, we would be invoking the GET call continuously; obviously causing an immense amount of network traffic.

总而言之,我们已经看到useEffect的一种用法,即获取数据。 我们还了解到,如果没有空的依赖关系数组,我们将连续调用GET调用; 显然会导致大量的网络流量。

However, we may want to refresh the data periodically and we used setInterval to accomplish this.

但是,我们可能需要定期刷新数据,并使用setInterval来完成此操作。

As always, I encourage to not only learn more about useEffect but experiment with this application and expand on it.

与往常一样,我不仅鼓励学习有关useEffect的更多信息,还请尝试使用该应用程序并对其进行扩展。

Thank you for reading and coding along.

感谢您的阅读和编码。

You may also enjoy:

您可能还会喜欢:

普通英语JavaScript (JavaScript In Plain English)

Enjoyed this article? If so, get more similar content by subscribing to Decoded, our YouTube channel!

喜欢这篇文章吗? 如果是这样,请订阅我们的YouTube频道解码,以获得更多类似的内容

翻译自: https://medium.com/javascript-in-plain-english/using-reacts-useeffect-hook-to-fetch-data-and-periodically-refresh-that-data-2a69b6d44081

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值