Hi! With inspiration of Nick Coughlin, I developed a pretty simple solution for using hash links or anchor links with React Router V6. As Nick proposes, it's without any further dependency like the popular react-router-hash-links
.
Target
Goal is that your app scrolls to a certain element with a certain ID, when a so called hash link or anchor link is used.
Example:
...
// react-router Link component
<Link to="/mypage#myheadline">Press Link to get to headline</Link>
...
By clicking this link, the user expects to be navigated to "/mypage" and scrolled to the element with ID "myheadline"
...
// headline with ID "myheadline"
<h2 id="myheadline">My Headline</h2>
...
ScrollToAnchor.tsx or jsx
Put this component anywhere within your router component. It simply listens for location changes and determines if there is a hash (or element ID) that your app should scroll to.
import { useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
function ScrollToAnchor() {
const location = useLocation();
const lastHash = useRef('');
// listen to location change using useEffect with location as dependency
// https://jasonwatmore.com/react-router-v6-listen-to-location-route-change-without-history-listen
useEffect(() => {
if (location.hash) {
lastHash.current = location.hash.slice(1); // safe hash for further use after navigation
}
if (lastHash.current && document.getElementById(lastHash.current)) {
setTimeout(() => {
document
.getElementById(lastHash.current)
?.scrollIntoView({ behavior: 'smooth', block: 'start' });
lastHash.current = '';
}, 100);
}
}, [location]);
return null;
}
export default ScrollToAnchor;
Top comments (4)
This component has been converted to an NPM package with the following improvements:
You can view the github repo here:
github > ncoughlin/scroll-to-hash-element
and the NPM repo here:
npm > scroll-to-hash-element
if you want scroll for after navbar, it's work for me:
Hello and thank you for this! Pardon my ignorance I am new to React JS, I have created a component, imported the function to the page I want to use it, but still not working, what am I missing please?
It's simple and works, Thankyou