我正在尝试从我的react应用程序上的服务器中获取实时JSON数据。我编写的代码很少能正常工作,无法连续获取,并且还会对服务器产生过多的请求,这会使浏览器非常慢。如何以更高效,更轻松的方式获取实时数据?预先感谢。
我使用Fetch API和setInterval向服务器请求数据,并使用react钩子更新数据。但是它执行的请求超出了我的想象,并且还会出现速度问题。
const [state, setState] = React.useState(0)
const devicePos = function () {
fetch('http://192.168.10.233:34599/')
.then(response => response.json())
.then(response => {
setState(response[0].x)
console.log(response[0].x)
})
.catch(error => {
console.log(error);
});
}
setInterval(function(){
devicePos()
}, 500);
我希望实时数据更新更快。
答案 0 :(得分:1)
应该将异步代码放入useEffect挂钩中,而不是将其放入setInterval中。作为响应,您需要在生命周期方法中进行异步调用,因为它们有副作用,就像您可能已经遇到的那样。 useEffect挂钩与类中的componentDidMount相似。不同之处在于,它带有更多功能,这意味着它可以处理所有三个生命周期方法componentDidMount, componentDidUpdate, componentWillUnmount
useEffect(() => {
devicePos();
}, []);
答案 1 :(得分:1)
我认为setInterval不是轮询数据的好方法。某些响应可能会比500毫秒慢,并且您稍后可能会得到较旧的结果。
每当您轮询时,您都应等待上一次响应。
const [state, setState] = React.useState(0)
const [timer, setTimer] = React.useState(null)
const [isMounted, setIsMounted] = React.useState(false)
async function updateDevicePosition () {
try {
const result = await fetch('http://192.168.10.233:34599/')
const data = await result.json()
setState(data.x)
} catch (e) {
console.error(e)
}
clearTimeout(timer)
setTimer(setTimeout(updateDevicePosition, 200))
}
useEffect(() => {
if (!isMounted) {
updateDevicePosition()
setIsMounted(true)
}
})
话虽这么说,这是对这项工作的许多要求。首选方式应该是在服务器引导数据的地方使用套接字,并且仅在更改设备位置时才向客户端发送消息。根据您何时使用此位置信息,您的应用将使用大量资源
答案 2 :(得分:-1)
您可以让它仅在响应返回(加上一些延迟)后重新提交获取。
const devicePos = () => {
fetch()
.then( res => res.json() )
.then( res => {
updateData();
} )
.catch( err => {
showError(err);
})
.finally( () => {
setTimeout( devicePos, 500 );
})
}
否则,您可能最终会使速度太慢的服务器瘫痪。
finally
确保无论api响应(或超时)如何,都将再次发送请求。