DEV Community

Kartik Budhiraja
Kartik Budhiraja

Posted on • Originally published at Medium on

Create horizontal scroll list with ScrollSpy in React

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:

Element.scrollIntoView()

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 call
  • scrollIntoView() 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:

    Source → (Array of references)

    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.

    Top comments (2)

    Collapse
     
    sainig profile image
    Gaurav Saini

    🤩 The horizontal scroll combined scrollspy is a really great use case. 👍

    Collapse
     
    kartikbudhiraja profile image
    Kartik Budhiraja

    SCROLLSPY!!! Thank you, I've been trying to remember this term throughout. It's just weird how your brain just forgets something totally. 🤦🏽‍♂️