i am getting uncaught error. too many re-renders.
what i am trying to do?
when a button is clicked start function is called and modal popup opens. once the start function is finished i have to close the modal popup.
below is the code,
enum CheckStatus {
INITIAL,
STARTING,
STARTED,
FINISHED,
FAILED,
}
const useSomeHook = (id) => {
const [status, setStatus] = React.useState(CheckStatus.INITIAL);
const start = React.useCallback(async () => {
setStatus(CheckStatus.STARTING);
let data= undefined;
try {
const { data: checkData } = await startCheck({
variables: { id },
});
data = checkData;
}
//some logic
React.useEffect(() => {
if (status === CheckStatus.STARTED ) {
stopPolling && stopPolling();
setStatus(Check Status.FINISHED);
//once status is finished then i have to close modal popup
}
}
return {
start,
status,
};
};
const Main = () => {
const [openModal,setOpenModal] = React.useState(false);
const {start,status} = useSomeHook(id);
return (
{openModal && (<Modal />)}
);
}
Now i want to set the openModal state to false when status is finished. so i do like below,
const Main = () => {
const [openModal,setOpenModal] = React.useState(false);
const {start,status} = useSomeHook(id);
if (status === CheckStatus.FINISHED) {
setOpenModal(false);
} //this gives error
return (
{openModal && (<Modal />)}
);
}
but gives this error
Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop
how can i fix this? is this right solution?
also is there a way to set the setOpenModal inside the useSomeHook as soon as status is set to FINISHED?
could someone help me fix this. thanks.
I'm not 100% sure, but I believe your issues is that you are setting a state every render, which in turn will always re-render, and re-set the state. The infinite loop. To work around this you should probably use useEffect
const Main = () => {
const [openModal,setOpenModal] = React.useState(false);
const {start,status} = useSomeHook(id);
React.useEffect(() => {
if (status === CheckStatus.FINISHED) {
setOpenModal(false);
}
}, [status]);
return (
{openModal && (<Modal />)}
);
}
which would only preform the if check whenever status is changed, instead of on every render.