Necesito desplazarme hacia arriba cada vez que la URL cambia en mi proyecto (y en la recarga de la página).
Todo funciona, pero tengo un problema con el botón Atrás del navegador. Incluso si el nombre de la ruta cambia, la página no se desplaza hacia arriba como debería, funciona en todos los demás casos (recarga de página y navegación de enlace regular).
Traté de contrarrestar eso creando un enlace personalizado solo para el botón Atrás, pero no se comporta como quiero. También probé un montón de otras cosas, pero nada parece funcionar en cuanto al botón Atrás del navegador.
import { useEffect, useState } from "react"; import { useLocation } from "react-router-dom"; const ScrollToTop = () => { const { pathname } = useLocation(); const useBackButton = () => { const [isBack, setIsBack] = useState(false); const handleEvent = () => { setIsBack(true); }; useEffect(() => { window.addEventListener("popstate", handleEvent); return () => window.removeEventListener("popstate", handleEvent); }); return isBack; }; const backButton = useBackButton(); console.log(backButton); useEffect(() => { window.scrollTo(0, 0); }, [pathname, backButton]); useEffect(() => { window.onbeforeunload = () => { window.scrollTo(0, 0); }; }, []); return null; }; export default ScrollToTop;No creo que el evento beforeunload sea necesario aquí, pero lo incluiré de todos modos. En lugar de usar un detector de eventos para el evento "popstate", puede usar el gancho useNavigationType para verificar expresamente un tipo de evento POP.
Nota : use window.addEventListener para el evento beforeunload para no contaminar/mutar el objeto de la window .
Ejemplo:
import { NavigationType, useLocation, useNavigationType } from "react-router-dom"; const useBackButton = () => { const navType = useNavigationType(); return navType === NavigationType.Pop; }; const useScrollToTop = () => { const { pathname } = useLocation(); const isPop = useBackButton(); const scrollToTop = () => window.scrollTo(0, 0); useEffect(() => { scrollToTop(); }, [pathname, isPop]); useEffect(() => { window.addEventListener("beforeunload", scrollToTop); return () => { window.removeEventListener("beforeunload", scrollToTop); }; }, []); };Uso:
function App() { useScrollToTop(); return ( ... ); }