Sometimes websites are overloaded with text, images, and other forms of content. The only way to fit all of this information on a screen is to allow scrolling. In this article, we will show you how to implement a scroll to bottom feature in React, which is useful for scrolling long lists, tables, or long content.

Forcing users to scroll all the way down isn’t a great UX practice, especially for users on the mobile.

In this article, we will show two ways to implement this feature.

One is to create a button takes users to the bottom after being clicked, and the other is to scroll to bottom automatically as soon as the container is displayed.

Let’s start with a button.

A button that scrolls to bottom in React

Let’s start with a simple example. A scrollable container with a header text and one button. Clicking this button will take you to the bottom of the scrollable container.

The scrollIntoView() is the native method available on the Element interface. When called on an element, it makes the element visible to the user. If you have a long scrollable container, you can call the scrollIntoView() method on <div> element to display its bottom end.

React components are usually written in JSX. If that’s the case, react scroll to bottom feature is easy to set up.

Simply create a button element and set its onClick event handler to call scrollIntoView() method on the main container. Use arguments to specify which part of the element (in this case, end / bottom) you want the user to see.

Let’s look at a code example:

import "./styles.css";
import { useRef } from "react";

export default function App() {
  const div = useRef(null);
  return (
    <div className="App" ref={div}>
      <h1>Welcome to web application</h1>
      <button
        onClick={() =>
          div.current.scrollIntoView({ behavior: "smooth", block: "end" })
        }
      >
        Scroll to bottom
      </button>
    </div>
  );
}

Here is the GIF that shows how the code works. You can also go to CodeSandbox to check out a live demo.

Scroll to bottom on mount in React

In the previous example, we have shown how to use the scrollIntoView() method to scroll to bottom of a React component after user clicks the button.

We can set up a React component to call this method whenever a component is mounted (displayed) to the page.

For class components, we should use the componentDidMount() lifecycle method. For functional components, we need to use the useEffect() hook.

In this example, scroll to bottom happens automatically as soon as the page is mounted.

import "./styles.css";
import { useRef, useEffect } from "react";
export default function App() {
  const div = useRef(null);
  useEffect(() =>
    div.current.scrollIntoView({ behavior: "smooth", block: "end" })
  );
  return (
    <div className="App" ref={div}>
      <h1>Welcome to web application</h1>
      <button
        onClick={() =>
          div.current.scrollIntoView({ behavior: "smooth", block: "end" })
        }
      >
        Scroll to bottom
      </button>
    </div>
  );
}

We provide the useEffect() hook with one argument: a callback function which will be executed when the component mounts (loads, displays) on the page. It is the exact same function we used as the onClick event handler.

The hook takes another argument – an array of state variables. React will ‘watch’ for changes in these state variables and execute the callback function whenever state variables are updated.

Refs in React

As a JavaScript developer, you may be used to getElementById() method. It is used to store an HTML element in a variable and use it within JavaScript code.

In React, we use something called refs to do the same. It references the DOM element.

In the example above, we have a functional component, so we utilize the useRef() hook to initialize a ref value and store it in the div variable. Then we set the ref attribute of the main <div> element to store a reference to the container.

Scroll to the bottom of the table in React

If you have a scrollable table with many rows of data, you can implement a feature to scroll to bottom of the table.

The principle is the same as we used before. We use the useRef() hook to store a reference to the <table> element in JSX.

Once you initialize the ref and store it in the tableRef variable, you need to set the ref attribute of <table> element to the tableRef variable, which stores a ref.

import "./styles.css";
import { useRef } from "react";
export default function App() {
  let tableRef = useRef(null);
  return (
    <div className="App">
      <h1>Statistics website</h1>
      <p>
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum."
      </p>
      <button
        onClick={() =>
          tableRef.current.scrollIntoView({ behavior: "smooth", block: "end" })
        }
      >
        Scroll to the bottom of table
      </button>
      <div className="table">
        <table ref={tableRef}>
            ...data
        </table>
      </div>
    </div>
  );
}

It is necessary to set the ref for <table> element, not the <div> that contains it, because the bottom of the <div> is not the same as bottom of the <table>.

In this case, we also have a button with a onClick event handler. It uses the same scrollIntoView() method to scroll to bottom of the table.

You can look at the live demo and source code on CodeSandbox.

Scroll to the bottom of the chat in React

Let’s review another example of scroll to bottom feature in React.

We have a rudimentary chat box, where we display <Message> components. Whenever user enters a new message, our component generates a new <Message> component and scrolls to the bottom of the chat.

We use the messages array to generate content for each component.

Similar to other chats, we also have the <input> field where users can enter their message and hit send.

In this example, we show how to implement scroll to bottom feature, so that the chat automatically scrolls to bottom when it is first loaded on the screen, as well as every time user adds a new message to the chat.

Check out the live demo on CodeSandbox.

import "./styles.css";
import { useState, useRef, useEffect } from "react";
export default function App() {
  const [messages, setMessages] = useState([
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eros donec ac odio tempor orci. Commodo ullamcorper a lacus vestibulum sed arcu.",
    "Faucibus ornare suspendisse sed nisi lacus sed viverra tellus in. Commodo sed egestas egestas fringilla phasellus. Leo a diam sollicitudin tempor id eu.",
    "Tincidunt praesent semper feugiat nibh sed. Quis blandit turpis cursus in hac habitasse platea dictumst quisque. Quam id leo in vitae turpis.",
    "Risus at ultrices mi tempus. Scelerisque fermentum dui faucibus in ornare quam viverra orci sagittis. Et netus et malesuada fames ac. Magna fermentum iaculis eu non diam phasellus vestibulum lorem.",
    "Odio aenean sed adipiscing diam donec adipiscing. Leo a diam sollicitudin tempor id eu nisl nunc mi. Eu scelerisque felis imperdiet proin fermentum leo vel orci porta.",
    "Lectus mauris ultrices eros in cursus turpis massa tincidunt. Rhoncus dolor purus non enim. At ultrices mi tempus imperdiet nulla malesuada.",
    "Vitae tortor condimentum lacinia quis. Viverra ipsum nunc aliquet bibendum enim. Vitae congue eu consequat ac felis donec et. Viverra mauris in aliquam sem."
  ]);
  const chatbox = useRef(null);
  useEffect(() => chatbox.current.scrollIntoView(false), [messages]);
  const [currentMessage, setCurrentMessage] = useState("");
  const handleClick = () => {
    setMessages([...messages, currentMessage]);
    setCurrentMessage("");
  };
  return (
    <div className="App">
      Enter text message:
      <input
        type="text"
        value={currentMessage}
        onChange={(e) => setCurrentMessage(e.target.value)}
      />
      <button onClick={() => handleClick()}>Send</button>
      <div className="chatbox">
        <div ref={chatbox}>
          {messages.map((message, index) => (
            <Message key={index} message={message} />
          ))}
        </div>
      </div>
    </div>
  );
}
const Message = (props) => {
  return (
    <div className="message">
      {props.message} <br></br>
      <p style={{ textAlign: "right" }}>Sent: 12PM</p>
    </div>
  );
};

This solution uses the useEffect() and useRef() hooks to execute the scrollIntoView() method on the <div> that contains the messages. Calling this method will scroll to the bottom of the chat in React.

Note that we have two <div> s that wrap around messages. One is a scrollable <div> with a fixed height, with a className value 'chatbox'. The other <div> is directly wrapped around the list of <Message> components and takes up the entire vertical space in the parent <div>. Therefore we need to scroll to the bottom of this latter div to scroll to the bottom of the chat.

If you try to scroll to the bottom of the parent scrollabe <div> with a fixed height, then it will not affect the scroll at all. The application will simply show the bottom border of fixed container.