Búsqueda de sitios web

javascript - Si actualizo la página matchMedia no funciona


Estoy usando matchMedia en React para colapsar mi SideBar cuando la página se redimensiona. Pero el problema es que si actualizo la página, mi barra lateral está abierta y no cerrada. Así que si quiero colapsar mi SideBar necesito redimensionar la página nuevamente o usar el botón de cerrar.

const layout = document.getElementById('home-layout');
const query = window.matchMedia('(max-width: 765px)');

  query.onchange = (evt) => {
      if( query.matches ) { 
        changeMenuMinified(true);
        layout.classList.add('extended-layout');
       } 
      else { 
        changeMenuMinified(false);
        layout.classList.remove('extended-layout');
      } 
    };
    query.onchange();
  };
  
  useEffect(() => {
    window.addEventListener('resize', handleResize);
  });

Si quito addEventListener funciona, puedo recargar la página y mi barra lateral permanece cerrada, pero si intento abrir la barra lateral con un botón, la barra lateral se cierra rápidamente

const handleResize = () => {

    const layout = document.getElementById('home-layout');
    const query = window.matchMedia('(max-width: 765px)');
    query.onchange = (evt) => {
      if( query.matches ) { 
        changeMenuMinified(true);
        layout.classList.add('extended-layout');
       } 
      else { 
        changeMenuMinified(false);
        layout.classList.remove('extended-layout');
      } 
    };
    query.onchange();
  };
  
  useEffect(() => {
    handleResize()
  });

  

barra lateral

Respuesta #1

Algunas cosas a considerar aquí:

  • Inicializa tu estado con el valor de coincidencia actual
  • Eliminar el listener en la función de limpieza del efecto
  • No olvides el array de dependencias de useEffect para evitar que tu código se ejecute en cada renderizado.

Puedes encontrar un ejemplo funcional aquí -> https://codesandbox.io/s/stack-72619755-lpwh6m?file=/src/index.js:0-613

const query = window.matchMedia('(max-width: 765px)')

const App = () => {
  const [minified, changeMenuMinified] = useState(query.matches)

  useEffect(() => {
    const resizeHandler = () => {
      if (query.matches) {
        changeMenuMinified(true)
      } else {
        changeMenuMinified(false)
      }
    }

    query.addEventListener("change", resizeHandler);

    return () => query.removeEventListener("change", resizeHandler);
  })

  return <p>{minified ? 'minified' : 'expanded'}</p>
}

Respuesta #2

Eso es porque necesitas tener ambos para funcionar, tanto al cargar como al residir, para eso puedes simplemente hacer esto:

Fíjate que añadí ese arreglo de dependencias vacío.

useEffect(() => {
    handleResize();
    window.addEventListener('resize', handleResize);
  },[]);