Running a Timer When a Tab Is Active
May 07, 2021
It should not be hard to send a request to an endpoint. From fetch
to axios
, there are many ways to achieve it. Using the setInterval()
or setTimeout()
, you can also send request(s) multiple times or after waiting for some time.
However, you might want to limit sending requests, if you are charged whenever you send a request. To get a response and update UI when a user actually sees your pages, the following a custom hook with the setInterval
inside of useEffect
might be helpful.
import React, { useState, useEffect } from "react";
/*
* Check whether a page is visible to a user.
* Return true if it is visible to the user. Return false otherwise.
*/
function usePageVisibility() {
const [isVisible, setIsVisible] = useState(getIsDocumentHidden());
const onVisibilityChange = () => setIsVisible(getIsDocumentHidden());
useEffect(() => {
const visibilityChange = getBrowserVisibilityProp();
document.addEventListener(visibilityChange, onVisibilityChange, false);
return () => {
document.removeEventListener(visibilityChange, onVisibilityChange);
};
});
return isVisible;
}
/*
* Component1 is React function component
* The value of isVisible is true when a user opens this tab. When the value is false and a user opens another tab
* (i.e, not this tab), it is not executed.
*/
const Component1 = () => {
const isVisible = usePageVisibility();
useEffect(() => {
let timerId = setInterval(async () => {
if (!isVisible) clearInterval(timerId);
let res = await axios.get(
`https://api.something.com/path`
);
// Update some states, if needed
// Send a request every 1000ms
}, 1000);
return () => clearInterval(timerId);
}, [isVisible]);
// ...
return (
<>
<div />
</>
);
}
References
Harnessing the Page Visibility API with React
Stop setInterval call in JavaScript
James Yoo