Last active
July 13, 2022 10:52
-
-
Save romanonthego/223d2efe17b72098326c82718f283adb to your computer and use it in GitHub Desktop.
Scroll to top with react hooks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect } from 'react'; | |
import { useRouter } from 'state'; | |
// Component that attaches scroll to top hanler on router change | |
// renders nothing, just attaches side effects | |
export const ScrollToTopControlller = () => { | |
// this assumes that current router state is accessed via hook | |
// but it does not matter, pathname and search (or that ever) may come from props, context, etc. | |
const { pathname, search } = useRouter(); | |
// just run the effect on pathname and/or search change | |
useEffect(() => { | |
try { | |
// trying to use new API - https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollTo | |
window.scroll({ | |
top: 0, | |
left: 0, | |
behavior: 'smooth', | |
}); | |
} catch (error) { | |
// just a fallback for older browsers | |
window.scrollTo(0, 0); | |
} | |
}, [pathname, search]); | |
// renders nothing, since nothing is needed | |
return null; | |
}; |
Smooth scroll doesn't always work for some reason. A workaround is to wrap it in a setTimeout
with zero time. This forces it to run after dom is ready after the render (I think).
setTimeout(() => {
window.scroll({
top: 0,
left: 0,
behavior: 'smooth',
});
}, 0);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for posting this, but I have a concern which you may not have considered, based on the assumption you would place this relatively top-level in the application JSX, around where application providers would typically live.
If that's the case, doesn't this scroll the window to the top on initial pageload? Is that ideal? Shouldn't it be on page change? What about hash/fragments that are intended to scroll the window down to a specific element (default browser behavior)?
You may want to consider firing the effect after pathname or search have changed. I'm not sure if this is ideal or correct but something to consider: