为什么当承诺被拒绝时,我的使用效应会无限地运行,但只有在实现时才一次?
我正在尝试在Axios的帮助下从使用JSON服务器创建的模拟后端获取数据。现在,当响应状态为200 IE时,数据成功获取了我的成功变量的状态,更改为true。使用效率仅运行一次,消息吐司仅出现一次。但是现在,当获取数据时出现错误时,使用效应会无限运行,吐司开始不停地出现一个不停的。有人可以向我解释为什么会发生这种情况,以及我如何解决这个问题?
以下是我编写的代码。
import React, { useState, useEffect } from 'react';
import Loader from './../components/Loader';
import axios from 'axios';
import { toast } from 'react-toastify';
const PostsTD = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState({
status: false,
message: '',
});
const [success, setSuccess] = useState(false);
const getPosts = () => {
axios
.get('http://localhost:5050/posts')
.then((res) => {
setPosts(res.data);
setLoading(false);
if (res.status === 200) setSuccess(true);
})
.catch((error) => {
setLoading(false);
setError({ status: true, message: error.message });
});
};
useEffect(() => {
getPosts();
if (error.status) {
toast.error(error.message);
}
if (success) toast.success('Success!');
}, [success, error]);
if (loading) {
return (
<div className="px-28 text-center py-12">
<Loader />
</div>
);
}
return (
<div className="md:px-28 px-6">
<h1 className="text-center font-extrabold text-gray-400 my-4 text-4xl">POSTS FETCHED USING AXIOS</h1>
{posts && posts?.length > 0 ? (
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 py-2 px-3 bg-red-500">
{posts?.map((post, idx) => {
return (
<div key={idx} className="p-3 bg-red-200 text-gray-900 rounded-md">
<h2 className="font-semibold text-xl">{post.title}</h2>
<p className="font-normal my-3">{post.body}</p>
</div>
);
})}
</div>
) : (
<h1>NO posts to render</h1>
)}
</div>
);
};
export default PostsTD;
I am trying to fetch data from a mock backend created using JSON-server with the help of Axios. Now when the response status is 200 i.e., data fetched successfully the state of my success variable changes to true. The useEffect runs only once and message toast appears only once. But now when there is an error while fetching the data the useEffect runs infinitely and toast starts appearing non-stop one after another. Can someone explain to me why is this happening and how am I able to solve this issue?
Below is the code I have written.
import React, { useState, useEffect } from 'react';
import Loader from './../components/Loader';
import axios from 'axios';
import { toast } from 'react-toastify';
const PostsTD = () => {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState({
status: false,
message: '',
});
const [success, setSuccess] = useState(false);
const getPosts = () => {
axios
.get('http://localhost:5050/posts')
.then((res) => {
setPosts(res.data);
setLoading(false);
if (res.status === 200) setSuccess(true);
})
.catch((error) => {
setLoading(false);
setError({ status: true, message: error.message });
});
};
useEffect(() => {
getPosts();
if (error.status) {
toast.error(error.message);
}
if (success) toast.success('Success!');
}, [success, error]);
if (loading) {
return (
<div className="px-28 text-center py-12">
<Loader />
</div>
);
}
return (
<div className="md:px-28 px-6">
<h1 className="text-center font-extrabold text-gray-400 my-4 text-4xl">POSTS FETCHED USING AXIOS</h1>
{posts && posts?.length > 0 ? (
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-3 py-2 px-3 bg-red-500">
{posts?.map((post, idx) => {
return (
<div key={idx} className="p-3 bg-red-200 text-gray-900 rounded-md">
<h2 className="font-semibold text-xl">{post.title}</h2>
<p className="font-normal my-3">{post.body}</p>
</div>
);
})}
</div>
) : (
<h1>NO posts to render</h1>
)}
</div>
);
};
export default PostsTD;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于错误在依赖项数组中,任何时候错误都会运行。因此,错误会改变,这会导致您获取帖子,这会导致错误更改等。
我将其分为单独的效果;一个开始负载,另一个要进行敬酒:
Since error is in the dependency array, any time the error changes, this effect will run. So the error changes, which causes you to get the posts, which causes the error to change, etc.
I would split this up into separate effects; one to kick off the load, and another to do the toasts:
您的使用效率在其逻辑中具有错误作为依赖项和getPosts,因此,如果GetPosts设置了错误(与此相同),则会创建一个无限的循环。
useeffect =&gt; getPosts =&gt; setError =&gt;使用效果...
您可以通过删除使用效果的误差依赖性来解决此问题,如果您仍然想恢复数据,我认为您应该直接在SetteMeut中的GetPosts中直接调用GetPosts。
Your useEffect has error as dependency and getPosts in its logic, so, if getPosts sets error (as it does) it creates an infinite loop.
useEffect => getPosts => setError => useEffect ...
You can resolve this by deleting the error dependency of your useEffect, if you still want to refetch data, I think you should directly call getPosts in getPosts in a setTimeout for example.
正如其他人以前提到的那样,您的问题与您的
useffect
触发另一个getPosts
在仅应对成功或错误变量的变化时进行反应时。在效果内进行API调用时,请考虑以下内容:(#1基于个人意见)
这就是我的结构方式:
As others have mentioned before, your problem is with your
useEffect
triggering anothergetPosts
call when it was only supposed to react to a change in success or error variables.When doing API calls inside an effect, please consider these: (#1 is based on personal opinion)
This is how I would probably structure it: