Reputation: 79
I'm trying to do something with setTimeout on a switch controller but I don't know what is the problem and I get this error when the code is run, this in fact is a custom hook I use: Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
import React from 'react';
const useVisibility = () => {
const [visibility, setVisibility] = React.useState(true);
const [firstTime, setFirstTime] = React.useState(true);
let timeOutId;
const removeTimer = () => {
clearTimeout(timeOutId);
timeOutId = 0;
};
React.useEffect(
() => {
document.addEventListener('visibilitychange', (e) => {
if (document.hidden) {
switch (firstTime) {
case true:
setFirstTime(false)
timeOutId = setTimeout(() => {
setVisibility(false);
}, 0);
break;
default:
timeOutId = setTimeout(() => {
setVisibility('closed');
}, 0);
break;
}
} else if (document.isConnected) {
removeTimer();
}
});
},
[visibility]
);
return { visibility, setVisibility };
};
export default useVisibility;
And here is how I'm using it, and also calling a React function inside it:
{
visibility === 'closed' ? <> {cheatingPrevent()}
<Modal onClose={() => setVisibility(true)}
title="test"
text="test." /> </> : null
}
Upvotes: 1
Views: 460
Reputation: 2452
React.useEffect
will add an event listener to document
every time visibility
changes as you have it in the dependency array. For each visibilitychange
event, all the duplicate event listeners added will run.
The problem with this is you're calling setVisibility
in useEffect
callback which updates visibility
which in return re-runs useEffect
.
You don't need visibility
in dependency array of useEffect
hook. Pass empty array []
Upvotes: 4