Как избежать повторного рендеринга бесконечного цикла из прослушивателя событий (React)

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть следующий функциональный компонент:

 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 (
<> </>
)}
 

Проблема в том, что

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

приводит к бесконечному циклу. Я проводил исследование и не нашел решения, которое подходит для этого случая. Я не могу поместить эту часть в функцию, поскольку мне всегда нужно проверять размер, а не только после нажатия на кнопку.
toggleMenu вызывается при нажатии на значок мобильной навигации.

Эта логика закрывает наложение мобильной навигации после изменения размера окна и отображения настольной навигации.

Спасибо

Комментарии:

1. Вы можете просто пропустить второй параметр useEffect() ( [] ), чтобы ваш прослушиватель событий изменения размера был установлен при монтировании компонента и удален перед размонтированием компонента.

Ответ №1:

Попробуйте это

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

Это будет обновляться в зависимости от изменения зависимости (isOpen).