phibiz
phibiz

Reputation: 47

How to avoid re-render infinite loop from event listener (React)

I have the following functional component:

export default function Nav({photo}) {
    const [isOpen, setIsOpen] = useState(false)

    const [width, setWidth] = useState(window.innerWidth);
    const breakpoint = 768;

    useEffect(() => {
        const handleWindowResize = () => setWidth(window.innerWidth)
        window.addEventListener("resize", handleWindowResize);

        return () => window.removeEventListener("resize", handleWindowResize);
    }, []);

    if(width >= breakpoint) {
        setIsOpen(false);
    }

    function toggleMenu() {
        setIsOpen(!isOpen);
        if(!isOpen) {
            disableBodyScroll(document.body);
        } else {
            enableBodyScroll(document.body);
        }
        return true;
    }
    return (
<> </>
)}

The problem is that the

    if(width >= breakpoint) {
        setIsOpen(false);
    }

results in an infinite loop. I was researching and did not find a solution that works for this case. I cannot put this part into a function since I always need to check for a resize and not just after I click on a button. The toggleMenu is called when the mobile nav icon is clicked.

This logic is closing the mobile nav overlay once the window is resized and the desktop nav is shown.

Thanks

Upvotes: 0

Views: 1203

Answers (1)

BARNOWL
BARNOWL

Reputation: 3609

Try this

useEffect(() => {
 if(width >= breakpoint) {
     setIsOpen(false);
 }
},[isOpen])

This will update, based on the dependency(isOpen) gets changed.

Upvotes: 1

Related Questions