DEV Community

Cover image for React useScrollTo hook
Satvik Daga
Satvik Daga

Posted on • Updated on

React useScrollTo hook

Ever since the introduction of hooks in React 16.8, they have become an integral part of every React devs arsenal.
Hooks solve a wide variety of seemingly unconnected problems in React that one may encounter over years of writing and maintaining tens of thousands of components.

Recently while I was working on one of my projects, I encountered a relatively common problem. I wanted to scroll to a component when its loaded on screen or on some other event. If you have worked with pure js, then there is a very simple solution using scrollIntoView function.

const elmnt = document.getElementById("content");
elmnt.scrollIntoView();
Enter fullscreen mode Exit fullscreen mode

Run the above code on that particular event and it works like a charm.

Now when I searched for a solution in React, I came across this library react-scroll. Its a react library for animating vertical scrolling that provides functionality to scroll to a component on an event. Its good but I didn't want to add another dependency and change the default scrolling I have been using in my app.

So here is a custom hook I came up with that scrolls to an element on an event like load or click.

const useScrollTo = <T extends Element>() => {
  const ref = useRef<T>(null);
  const [shouldScrollTo, setShouldScrollTo] = useState(false);

  useEffect(() => {
    if (ref.current && shouldScrollTo) {
      ref.current.scrollIntoView({ behavior: 'smooth' });
      setShouldScrollTo(false);
    }
  }, [shouldScrollTo]);

  return [ref, setShouldScrollTo];
};

// Scroll to the element on component load
const Example1: FunctionComponent = () => {
  const [scrollToRef, setShouldScrollTo] = useScrollTo();

  useEffect(()=> {
    setShouldScrollTo(true)
  }, [setShouldScrollTo]);

  return (
    <HTMLElementToScrollTo ref={scrollToRef}/>
    {/* Some Other Components */}
  )
}

// Scroll to the element on click 
const Example2: FunctionComponent = () => {
  const [scrollToRef, setShouldScrollTo] = useScrollTo();

  return (
    <HTMLElementToScrollTo ref={scrollToRef}/>
    {/* Some Other Components */}
    <HTMLElementToClick onClick={() => setShouldScrollTo(true)} />
  )
}
Enter fullscreen mode Exit fullscreen mode

You can checkout this demo that uses this hook to scroll to the first and last image on a button click.

GitHub logo dagasatvik10 / react-useScrollTo-demo

Demo of useScrollTo hook in React

Top comments (2)

Collapse
 
eqbit profile image
Nick

Thanks, very useful
Small hint: in ref.current!.scrollIntoView there is no for ! due to ref.current check in the above line

Collapse
 
dagasatvik10 profile image
Satvik Daga

Thanks for pointing that out @eqbit