Skip to content

Instantly share code, notes, and snippets.

@ericdcobb
Created April 1, 2021 17:16
Show Gist options
  • Save ericdcobb/b9dc0e9d985c8bd0d9a3ecf9ec87d417 to your computer and use it in GitHub Desktop.
Save ericdcobb/b9dc0e9d985c8bd0d9a3ecf9ec87d417 to your computer and use it in GitHub Desktop.
const scrollToLocation = () => {
const scrolledRef = React.useRef(false);
const { hash } = useLocation();
React.useEffect(() => {
if (hash && !scrolledRef.current) {
const id = hash.replace('#', '');
const element = document.getElementById(id);
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
scrolledRef.current = true;
}
}
});
};
@spencersteers
Copy link

The only thing would be if you want changes in the hash to trigger the scroll again

@ericdcobb
Copy link
Author

ericdcobb commented Apr 1, 2021

Updated to support scrolling again when the hash updates:

const useScrollToLocation = () => {
  const scrolledRef = React.useRef(false);
  const { hash } = useLocation();
  const hashRef = React.useRef(hash);

  React.useEffect(() => {
    if (hash) {
      // We want to reset if the hash has changed
      if (hashRef.current !== hash) {
        hashRef.current = hash;
        scrolledRef.current = false;
      }

      // only attempt to scroll if we haven't yet (this could have just reset above if hash changed)
      if (!scrolledRef.current) {
        const id = hash.replace('#', '');
        const element = document.getElementById(id);
        if (element) {
          element.scrollIntoView({ behavior: 'smooth' });
          scrolledRef.current = true;
        }
      }
    }
  });
};

@yelnyafacee
Copy link

hi, how can I adapt this to work with Next-js? need to use it with intersection observer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment