How to Scroll to an Element on Click in React

Last updated on April 25, 2023
How to Scroll to an Element on Click in React

To scroll to an element on click in React:

  1. Set a ref on the target element.
  2. Set a click listener on the element meant to cause the scroll on click.
  3. In the click event listener, call the scrollIntoView() method on the ref object.
import { useRef } from 'react';

export default function App() {
  const ref = useRef(null);

  const handleClick = () => {
    ref.current?.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <div>
      <button onClick={handleClick}>Scroll to element</button>

      <div style={{ height: '150rem' }} />

      <div ref={ref} style={{ backgroundColor: 'lightblue' }}>
        Coding Beauty
      </div>

      <div style={{ height: '150rem' }} />
    </div>
  );
}
Scrolling to an element on click in React

Scrolling to an element on click improves user experience by allowing for quick navigation, especially for long lists or pages with multiple sections. It can also add a touch of interactivity to navigation through smooth-scrolling animations.

We create a ref object with the useRef hook and assign it to the ref prop of the target div element. Doing this sets the current property of the ref object to the DOM object that represents the element.

useRef returns a mutable object that maintains its value when a component updates. Also, modifying the value of this object’s current property doesn’t cause a re-render. This is unlike the setState update function return from the useState hook.

We use the onClick on the button to a click listener to it. So, this listener will be called when the user clicks the button.

const handleClick = () => {
  ref.current?.scrollIntoView({ behavior: 'smooth' });
};

In the handleClick listener, we call the scrollIntoView() method on the ref of the target div element to scroll down to it and display it to the user.

We set the behaviour option to smooth to make the element scroll into view in an animated way, instead of jumping straight to the element in the next frame - auto. auto is the default.

Scroll to dynamic element on click in React

We can do something similar to scroll to a dynamically created element in React:

import { useRef, useState } from 'react';

const allFruits = [
  'Apples',
  'Bananas',
  'Oranges',
  'Grapes',
  'Strawberries',
  'Blueberries',
  'Pineapples',
  'Mangoes',
  'Kiwis',
  'Watermelons',
];

export default function App() {
  const ref = useRef(null);

  const [fruits, setFruits] = useState([...allFruits.slice(0, 3)]);

  const addFruit = () => {
    setFruits((prevFruits) => [...prevFruits, allFruits[prevFruits.length]]);
  };

  const scrollToLastFruit = () => {
    const lastChildElement = ref.current?.lastElementChild;
    lastChildElement?.scrollIntoView({ behavior: 'smooth' });
  };

  return (
    <div>
      <div
        style={{
          position: 'fixed',
          backgroundColor: 'white',
          bottom: 0,
          marginBottom: 10,
        }}
      >
        <button onClick={addFruit}>Add fruit</button>
        <button onClick={scrollToLastFruit} style={{ marginLeft: '8px' }}>
          Scroll to last
        </button>
      </div>

      <div style={{ height: '5rem' }} />

      <div ref={ref}>
        {fruits.map((fruit) => (
          <h2 key={fruit}>{fruit}</h2>
        ))}
      </div>

      <div style={{ height: '150rem' }} />
    </div>
  );
}
Scrolling to a dynamic element on click in React.

Here we have a list of fruits displayed. The Add fruit button dynamically adds an item to the fruit list on click. Then the Scroll to last button scrolls to this item on click, as it's the last in the list.

Like before, we use the onClick prop to set a click event listener on the button.

This time we set the ref on the list instead of the items since the items are created dynamically, and the last item will not be constant. Doing this sets the current property of the ref object to the DOM object that represents the list element.

In this listener, we use the lastElementChild property of the list element to get its last item element. Then we call scrollIntoView() on this last item to scroll down to it.

const scrollToLastFruit = () => {
  const lastChildElement = ref.current?.lastElementChild;
  lastChildElement?.scrollIntoView({ behavior: 'smooth' });
};

Create and scroll to dynamic element on click

We can also combine the element creation and scroll as a single action caused by a button click.

To do this, we'll add a useEffect hook to call scrollToLastFruit() whenever the fruits state array changes.

const addFruit = () => {
  setFruits((prevFruits) => [...prevFruits, allFruits[prevFruits.length]]);
};

const scrollToLastFruit = () => {
  const lastChildElement = ref.current?.lastElementChild;
  lastChildElement?.scrollIntoView({ behavior: 'smooth' });
};

// 👇 Call `scrollToLastFruit()` when `fruits` changes.
useEffect(() => {
  scrollToLastFruit();
}, [fruits]);
Creating and scrolling to a dynamic element on click in React.

Here's the full code for reference:

import { useEffect, useRef, useState } from 'react';

const allFruits = [
  'Apples',
  'Bananas',
  'Oranges',
  'Grapes',
  'Strawberries',
  'Blueberries',
  'Pineapples',
  'Mangoes',
  'Kiwis',
  'Watermelons',
];

export default function App() {
  const ref = useRef(null);

  const [fruits, setFruits] = useState([...allFruits.slice(0, 3)]);

  const addFruit = () => {
    setFruits((prevFruits) => [...prevFruits, allFruits[prevFruits.length]]);
  };

  const scrollToLastFruit = () => {
    const lastChildElement = ref.current?.lastElementChild;
    lastChildElement?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    scrollToLastFruit();
  }, [fruits]);

  return (
    <div>
      <div
        style={{
          position: 'fixed',
          backgroundColor: 'white',
          bottom: 0,
          marginBottom: 10,
        }}
      >
        <button onClick={addFruit}>Add fruit and scroll</button>
      </div>

      <div style={{ height: '5rem' }} />

      <div ref={ref}>
        {fruits.map((fruit) => (
          <h2 key={fruit}>{fruit}</h2>
        ))}
      </div>

      <div style={{ height: '150rem' }} />
    </div>
  );
}

Key takeaways

  • To scroll to an element on click in React, set a ref on the target element, set a click listener on the element meant to cause the scroll, and in the click event listener, call the scrollIntoView() method on the ref object.
  • To scroll to a dynamically created element in React, set the ref on the list container and call scrollIntoView() on the target item element.
  • We can combine element creation and scrolling as a single action by using the useEffect hook to call scrollToLastFruit() whenever the state array changes.
Coding Beauty Assistant logo

Try Coding Beauty AI Assistant for VS Code

Meet the new intelligent assistant: tailored to optimize your work efficiency with lightning-fast code completions, intuitive AI chat + web search, reliable human expert help, and more.

See also