[英]React useEffect does infinite loop
My useEffect is getting data from web api.我的 useEffect 正在从 web api 获取数据。 I want to render all posts on home page and trigger again my useEffect when someone create new post.
我想在主页上呈现所有帖子,并在有人创建新帖子时再次触发我的 useEffect。 The problem is when I put dependancy on useEffect its start doing endless requests.
问题是当我依赖 useEffect 它开始做无休止的请求时。 When I pass empty array as dependancy, when someone create new post it doesnt render on home page until I refresh the page.
当我将空数组作为依赖项传递时,当有人创建新帖子时,它不会在主页上呈现,直到我刷新页面。 I read a lot in internet about that problem but still I dont know how to do it.
我在互联网上阅读了很多关于这个问题的信息,但我仍然不知道该怎么做。 Thanks
谢谢
function App() {
const [posts, setPosts] = useState([]);
useEffect(() => {
const jwt = localStorage.getItem("jwt");
fetch('https://localhost:44366/api/Posts/getAllPosts',
{
method: "GET",
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + jwt
},
})
.then(r => r.json()).then(result => setPosts(result));
}, [posts]);
return (
<div >
<Router>
<Header />
<main className="App">
{
posts.map(post => (
<Post keyToAppend={post.CreatedOn} username={post.User.FirstName} title={post.Title} content={post.Content} images={post.ImageUrls} avatarImage={post.User.MainImageUrl} />
))
}
</main>
</Router>
<Footer />
</div>
);
}
Post component:帖子组件:
const Post = ({ keyToAppend, username, title, content, images, avatarImage }) => {
return (
<div className="post" key={keyToAppend}>
<div className="post__header">
<Avatar
className="post__avatar"
alt="avatar"
src={avatarImage}
/>
<h3 className="username">{username}</h3>
</div>
<h1 className="title">{title}</h1>
<p className="content">{content}</p>
<p>
{typeof images != "undefined" ? <ImageSlider slides={images} /> : ""}
</p>
</div>
)
}
export default Post;
Remove posts
from the dependency array, so it's just []
.从依赖数组中删除
posts
,所以它只是[]
。 That will run the effect once, when the component loads.这将在组件加载时运行一次效果。
useEffect(() => {
const jwt = localStorage.getItem("jwt");
fetch('https://localhost:44366/api/Posts/getAllPosts',
{
method: "GET",
headers: {
"Content-Type": "application/json",
'Authorization': 'Bearer ' + jwt
},
})
.then(r => r.json()).then(result => setPosts(result));
}, []);
// ^^−−−−− remove `posts` here
The reason it runs endlessly with your current code is that your effect callback changes the posts
state member, which triggers the effect again (because posts
is in the dependency array).它与您当前的代码无休止地运行的原因是您的效果回调更改了
posts
state 成员,这再次触发了效果(因为posts
在依赖项数组中)。 You only need to include things in the dependency array that you read in the effect callback.您只需要在效果回调中读取的依赖数组中包含内容。 You never read
posts
in the effect callback.您从不阅读效果回调中的
posts
。
Side note: That code is falling prey to the fetch
API footgun I describe here .旁注:该代码正在成为我 在此处描述的
fetch
API footgun 的牺牲品。 You need to check r.ok
before calling r.json
(and handle errors):您需要在调用
r.json
r.ok
并处理错误):
useEffect(() => {
const jwt = localStorage.getItem("jwt");
fetch("https://localhost:44366/api/Posts/getAllPosts", {
method: "GET",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + jwt
},
})
.then(r => {
if (!r.ok) { // <=================
throw new Error(`HTTP error ${r.status}`);
}
return r.json();
})
.then(result => setPosts(result))
.catch(error => {
// ...handle/report error here...
});
}, []);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.