18

I am currently building a card section which shows a horizontal list of cards. This list overflows, which makes the user have to scroll horizontally to view the offscreen cards.

To make this process easier for the user, I want to create buttons which scroll the horizontal list to the left or right.

I tried solving this by creating a reference to the horizontal list and apply a scrollX when I click on the previously mentioned button. This however, results in the following error:

Cannot add property scrollX, object is not extensible

My code:

const ref = useRef(null);

const scroll = () => {
  ref.scrollX += 20;
};

return (
  <div className={style.wrapper} id={id}>
    <Container className={style.container}>
      <Row>
        <Col>
          <button onClick={scroll}>TEST</button>
        </Col>
      </Row>
    </Container>
    <div className={style.projects} ref={ref}>
      {projects.map((data, index) => (
        <CardProject
          key={index}
          title={data.title}
          image={data.image}
          description={data.description}
        />
      ))}
    </div>
  </div>
);

1 Answer 1

47

In order to access a DOM Node with a Ref, you need to use ref.current; useRef is a container for a DOM node and you access that node with the current property.

Additionally, scrollX is a read-only property; you need to call scrollLeft to change the scroll position. For scrollLeft to work, you need to add an overflow-x: scroll; rule to the style.projects for it to work. (If style.projects is an object than change to overflowX: 'scroll'.)

To be able to scroll left or right, your can add a parameter to the function for the scroll offset, so it doesn't always scroll right:

const scroll = (scrollOffset) => {
  ref.current.scrollLeft += scrollOffset;
};

For this to work, you'll need two buttons in your JSX that pass in the offset values for left or right to the scroll function:

 <Row>
        <Col>
          <button onClick={() => scroll(-20)}>LEFT</button>
          <button onClick={() => scroll(20)}>RIGHT</button>
        </Col>
  </Row>
Sign up to request clarification or add additional context in comments.

3 Comments

Is it also possible to make this scroll behaviour smooth?
@JonathanLauwers You can add scroll-behavior: smooth; to the CSS for the style.projects but that isn't natively supported in Safari so you'd need some sort of polyfill like github.com/iamdustan/smoothscroll
Is this working? I tried it but not working as ittended

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.