es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

React Hook Toggle clase en cambio de tamaño de la ventana

Estoy intentando construir un menú móvil simple con un event listener que eliminaría la clase de alternancia ‘is-open’ cada vez que se redimensiona la ventana (en el cuerpo, el botón y el menú). No tengo mucha confianza en la sintaxis, la alternancia parece funcionar pero no puedo poner todas las piezas juntas. ¡Cualquier ayuda sería muy apreciada amablemente!

import React, {useState, useEffect} from 'react';

function NavigationMobile() {

const [isOpen, setIsOpen] = useState(false);
  const toggle = () => setIsOpen(!isOpen);
  const [isMobile, setIsMobile] = useState(window.innerWidth < 991);

useEffect(() => {
    document.body.classList.toggle('is-open', isOpen);
  },[isOpen])

useEffect(() => {
    window.addEventListener("resize", () => {
      const ismobile = window.innerWidth < 991;
      if (ismobile !== isMobile) setIsMobile(ismobile);
    }, false);
  }, [isMobile]);

return (
    <wrapper>

  <button className={`nav-link btn-icon menu ${isOpen ? 'is-open' : ''}`} onClick= {toggle} aria-label="Open Menu">


  <div classname="{`mobile-menu" ${isopen="" 'is-open'="" :="" ''}`}="">

    <div classname="mobile-menu-inner">

    </div>

  </div>

</wrapper>
)

}

export default NavigationMobile;
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El código proporcionado parece lograr la funcionalidad de alternar, pero hay algunos cambios que se pueden hacer para lograr el efecto deseado de eliminar la clase ‘is-open’ en el body, el botón y el menú cada vez que la ventana cambie de tamaño.

    Primero, necesitamos añadir una función que elimine la clase ‘is-open’ al gancho useEffect que escucha los cambios en el tamaño de la ventana. Dentro de la función, usaremos document.body.classList, button.classList y menu.classList para alternar la clase ‘is-open’.

    useEffect(() => {
        window.addEventListener("resize", () => {
          const ismobile = window.innerWidth < 991;
          if (ismobile !== isMobile) setIsMobile(ismobile);
    
          // añadir removeIsOpen para eliminar la clase 'is-open' cada vez que la ventana cambie de tamaño
          const removeIsOpen = () => {
            document.body.classList.remove('is-open');
            button.classList.remove('is-open');
            menu.classList.remove('is-open');
          }
    
          removeIsOpen();
        }, false);
      }, [isMobile]);
    

    A continuación, necesitamos añadir referencias (refs) a los elementos del botón y el menú para poder referenciarlos en la función removeIsOpen.

    const buttonRef = useRef(null);
      const menuRef = useRef(null);
    
      return (
        <wrapper>
    
          {/* añadir ref al botón */}
          <button ref="{buttonRef}" classname="{`nav-link" btn-icon="" menu="" ${isopen="" 'is-open'="" :="" ''}`}="" onclick="{toggle}" aria-label="Open Menu">
          </button>
    
          {/* añadir ref al menú */}
          <div ref="{menuRef}" classname="{`mobile-menu" ${isopen="" 'is-open'="" :="" ''}`}="">
    
            <div classname="mobile-menu-inner">
    
            </div>
    
          </div>
    
        </wrapper>
      )
    

    Finalmente, necesitamos actualizar el primer gancho useEffect que alterna la clase ‘is-open’ en el body con las refs a los elementos del botón y el menú.

    useEffect(() => {
        // añadir buttonRef y menuRef para alternar la clase 'is-open'
        document.body.classList.toggle('is-open', isOpen);
        buttonRef.current.classList.toggle('is-open', isOpen);
        menuRef.current.classList.toggle('is-open', isOpen);
      },[isOpen])
    

    Con estos cambios, la clase ‘is-open’ se eliminará de los elementos del body, botón y menú cada vez que la ventana cambie de tamaño, como se desea.

Comments are closed.