Reputation: 5
I am trying to fetch the real-time JSON data from the server on my react app. The code that I write works rarely, continuously fail to fetch and also it creates too much request to the server which makes the browser really slow. How can I fetch the real-time data in a more efficient and less buggy way? Thanks in advance.
I used Fetch API and setInterval to request the data to the server and used react hooks to update the data. But it is doing too much request than I thought and also occurs a speed problem.
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);
I hope the real-time data updates faster.
Upvotes: 0
Views: 7975
Reputation: 3982
I don't think setInterval is a good way for polling data. Some responses might be slower than 500 ms and you might get older results later.
Whenever you poll, you should wait for previous response.
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)
}
})
That being said, this is a lot of requests for such job. Preferred way should be to use a socket where server is leading data and only sending messages to your client when device position is changed. Depending on when you'll use this position information, your app will be using lot's of resources
Upvotes: 1
Reputation: 619
instead of putting it in setInterval, asynchronous code should go in the useEffect hook. In react you need to do your async calls in lifecycle methods because they have side effects, as you were probably already experiencing. The useEffect hook is similar to componentDidMount in classes. The difference is that it comes with more in the box, meaning it handles all three lifecycle methods, componentDidMount, componentDidUpdate, componentWillUnmount
useEffect(() => {
devicePos();
}, []);
Here is the docs as to how it works
Upvotes: 2
Reputation: 84
You could have it only resubmit the fetch when the response comes back (plus some delay).
const devicePos = () => {
fetch()
.then( res => res.json() )
.then( res => {
updateData();
} )
.catch( err => {
showError(err);
})
.finally( () => {
setTimeout( devicePos, 500 );
})
}
Otherwise, you might end up bogging down a server that is too slow.
The finally
ensures that regardless of the api response (or timeout), the request is sent again.
Upvotes: -1