简体   繁体   中英

setTimeout React: too many re-renders

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. 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
}

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 []

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM