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();
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)} />
)
}
You can checkout this demo that uses this hook to scroll to the first and last image on a button click.
Top comments (2)
Thanks, very useful
Small hint: in
ref.current!.scrollIntoView
there is no for!
due toref.current
check in the above lineThanks for pointing that out @eqbit