A horizontal scroll list can be implemented easily, thanks to the flexbox. The tricky and fun part is not only highlighting the active heading as well as bringing it into view as the user scrolls down the page.
In this blog, we will discuss how to get this user experience.
Libraries used: react-scroll
Let's assume we have a row of headings.
These headings are embedded in Link from react-scroll and scroll down to respective part on click.
React Scroll has the following prop which would make it super easy to set an active category:
onSetActive — invoke whenever link is being set to active
The issue to solve inside this prop is to get the active category to be visible on the screen if the user scrolls down to it.
To get an element into the view, we would use:
To get access to the DOM element of the active category, we will use refs. It’s the recommended way of getting to access DOM nodes or React elements created in the render method.
We need to store the ref to the
item, and then callscrollIntoView() on the element when the user reaches that category.
As we have multiple categories, we would need to store refs in an array. But as I experimented with it, I found out for some reason, refs get wiped out when stored in an array.
With some research I found this comment:
Storing each ref as string worked, but considering the comment was made in 2014, and react has evolved a lot since I was a bit skeptical.
And even though it worked, I got the following warning in console:
Warning: A string ref, “1”, has been found within a strict mode tree. String refs are a source of potential bugs and should be avoided. We recommend using useRef() or createRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref
Also in the documentation for refs, it is clearly stated:
We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases.
The array does not work, and storing string ref is not an elegant solution.
So I thought of creating refs for each category heading using React.createRef() in the constructor.
And it worked like a charm, we can access the element in the following way in the callback of setting active category:
And the refs can be added to the respective DOM element like this:
And Voila!! 🤩
🥳 There we have our horizontal scroll list, scrolling the active heading into view as the user scrolls down.
This is the code sandbox for a working example:
Thank you for reading. If you have any questions or suggestions, please let me know in the comment box.