问题描述
我正在我的 React 应用程序中从 API(使用 json-server 构建的假 REST API)获取数据。我希望应用程序自动更新,而无需在 API 中发生任何更改时手动刷新。我该怎么做呢?代码如下:
import './App.css'
import React,{useState,useEffect} from 'react'
import axios from 'axios'
export default function App() {
const [post,setPost]=useState([])
const url="http://localhost:3000/users"
useEffect(()=>{
axios
.get(url)
.then(res=>{
setPost(res.data)
})
.catch(err=>{
console.log(err)
})
},[])
const showUsers=
post.map(item=>{
return(
<div className="card" key={item.id}>
<h2>Name: {item.name}</h2>
<h3>Username: {item.username}</h3>
<p>Email:{item.email}</p>
</div>
)
})}
return (
<div className="container">
{showUsers}
</div>
)
}
注意我试图将 post
状态变量放入 useEffect
钩子的依赖数组中,它按我的意愿工作,但它开始发送无限的 {{1 }} 到服务器。类似的东西
get requests
解决方法
默认情况下 useEffect 在每次更新时运行。
如果你给 ,[post])
如果某些值(post)在重新渲染之间没有改变,它告诉 React 跳过应用效果。
如果您只想在挂载时获取,请使用 ,[])
react 文档很好地解释了这一点: Optimizing Performance by Skipping Effects
,首先,让我们谈谈为什么将 post
放在 useEffect
依赖项中会导致无限请求。如前所述:
如果某些值在重新渲染之间没有改变,你可以告诉 React 跳过应用效果。
但问题是每次调用效果时,实际上是通过调用 post
来更改 setPost
。这会导致重新渲染。当 react 正在重新渲染时,它会检查是否应该再次运行效果。由于 post
中的变量 useEffect
发生了变化,react 决定再次运行效果。这会导致无限循环。
回到你的主要问题。如果我理解正确,您希望将您的应用程序状态与关于 posts
的服务器状态同步。您可以通过 polling or websockets 来实现。在轮询中,客户端每隔几秒钟向服务器发送一个请求,以检查状态是否有任何变化。 websockets 使得在服务器和客户端之间建立双向连接成为可能。双向连接使得服务器可以随时向客户端发送信息。
下面是针对您的问题的非常简单的投票解决方案。我强烈建议您阅读有关该概念的更多信息。
// ommited code
const [post,setPost]=useState([])
const url="http://localhost:3000/users"
const WAIT_TIME = 5000;
useEffect(() => {
const id = setInterval(() => {
axios
.get(url)
.then(res=>{
setPost(res.data);
})
.catch(err=>{
console.log(err);
})
},WAIT_TIME);
return () => clearInterval(id);
},[post]);
// omitted code