Skip to content

Instantly share code, notes, and snippets.

@romanonthego
Last active July 13, 2022 10:52
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save romanonthego/223d2efe17b72098326c82718f283adb to your computer and use it in GitHub Desktop.
Save romanonthego/223d2efe17b72098326c82718f283adb to your computer and use it in GitHub Desktop.
Scroll to top with react hooks
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;
};
@ultim8k
Copy link

ultim8k commented Jul 13, 2022

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