How to Implement Scroll to Bottom Feature in React

Irakli Tchigladze Feb 02, 2024
  1. The Scroll-to-Bottom Feature in React
  2. Create Class Components to Implement Scroll-to-Bottom Feature in React
  3. Create Functional Components to Implement Scroll-to-Bottom Feature in React
How to Implement Scroll to Bottom Feature in React

Modern applications are sometimes overloaded with information, so scrolling is one of the features that help developers manage customers’ attention and provide a good user experience.

React is a library for building blazing fast single-page applications. React developers can build applications with modern features to provide the best user experience.

Naturally, there may be a question, how to implement scrolling features in React? This article will explore how to add the scroll to bottom feature in React.

The Scroll-to-Bottom Feature in React

To implement an automatic scroll to the bottom of a container element in React, we will use refs and the native Element.scrollIntoView() method.

Definition of refs in React

Web developers generally use refs to store a reference to an HTML element in a variable. They can use this variable in their JavaScript functions and methods.

In short, refs make it easier to work with elements in JavaScript.

Since React does not deal with DOM directly, the official docs of the library recommend using as few refs as possible. Still, refs are necessary if you want to scroll to the bottom of a container in React.

The Element interface allows us to call methods on the elements themselves. The scrollIntoView() is one of those methods we can use to force scroll to a particular element to make sure it appears on the user’s screen.

As you might’ve guessed, we will use refs to specify which element we want to focus on.

Create Class Components to Implement Scroll-to-Bottom Feature in React

Since introducing ES6 syntax, React developers can easily write class components. Let’s explore how to implement a scroll to bottom feature in React class components without further ado.

class Messages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      messages: [
        "message 1",
        "message 2",
        "message 3",
        "message 4",
        "message 5",
        "message 6",
        "message 7",
        "message 8",
        "message 9",
        "message 10",
        "message 11",
        "message 12",
        "message 13",
        "message 14",
        "message 15",
        "message 16",
        "message 17",
        "message 18"
      ]
    };
  }
  messagesEndRef = React.createRef();

  componentDidMount() {
    this.scrollToBottom();
  }
  componentDidUpdate() {
    this.scrollToBottom();
  }
  scrollToBottom = () => {
    this.messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
  };
  render() {
    return (
      <div>
        {this.state.messages.map((message) => (
          <h1>{message}</h1>
        ))}
        <div ref={this.messagesEndRef} />
      </div>
    );
  }
}
export default Messages;

If you check out this live demo, you’ll notice that in this application, we have a scrollable container full of <h1> elements meant to represent the messages in your application. Every time the application reloads, the user is automatically taken to the bottom of the page.

So, if you have an online chat, you could implement this feature to take them to the most recent messages on the bottom every time they reload the page.

Now, let’s digest what goes on in the code.

  1. Here, we have a Messages class component. First, we create a messagesEndRef variable and set it to the React.createRef() method to initialize the ref.

  2. Then, we create an empty <div> element at the bottom of the container and set its ref attribute to this.messagesEndRef.

    This is necessary because an empty <div> does not take up any space, so it will not be noticeable to the naked eye. By placing it after the <h1> elements, we ensure that it will always be the last element in the parent container.

    Therefore, it’s a perfect element to use as a reference point to scroll to the bottom.

  3. In JSX, curly braces are necessary to write any JavaScript expression, such as referencing a class instance’s messagesEndRef property.

    For the next step, we must write a scrollToBottom() function to scroll to the bottom. Within this function, we access the current property of messagesEndRef variable and call the scrollIntoView() method.

    It’s unnecessary, but we can specify that the scroll should be smooth. This option will provide a much better user experience.

  4. Then, we use the lifecycle methods, componentDidMount() and componentDidUpdate(), to call the scrollToBottom() method defined on this class. The componentDidMount() lifecycle method will execute this function every time the component loads.

    So whenever users load your messaging app, they will be taken to the bottom to read the most recent message. The componentDidUpdate() lifecycle method will call this function when the state property changes.

    Every time a new message is added to the state, the component will re-render and take the user to the most recent message.

  5. Finally, we return a simple <div> container. Here, we go over all the values in the state property and display them as <h1> elements.

    We also have an empty <div>, which we use as an anchoring point to tell React where to scroll.

Create Functional Components to Implement Scroll-to-Bottom Feature in React

Since the release of React v16.8, functional components have all the features that used to be exclusive to Class components.

Specifically, you can use the useState() feature to initialize the state in functional components. The useRef() hook can replace the lifestyle methods from the previous example.

Also, instead of the createRef() method, we import the useRef() hook from the core react package.

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

const Messenger = () => {
  const [messages, setMessages] = useState([
        "message 1",
        "message 2",
        "message 3",
        "message 4",
        "message 5",
        "message 6",
        "message 7",
        "message 8",
        "message 9",
        "message 10",
        "message 11",
        "message 12",
        "message 13",
        "message 14",
        "message 15",
        "message 16",
        "message 17",
        "message 18"
      ])
  const bottom = useRef(null)

  const scrollToBottom = () => {
    bottom.current.scrollIntoView({ behavior: "smooth" })
  }

  useEffect(() => {
    scrollToBottom()
  }, [messages]);

  return (
    <div>
          {messages.map(message => <h1>{message}</h1>)}
          <div ref={bottom}></div>
    </div>
  )
}

Now, let’s digest the code example above.

  1. First, we initialized the state and set it equal to the array of messages. The useState() hook also created an updater function, so we can add more messages if needed.

  2. Then, we initialized a ref using the useRef() hook and stored it in the bottom variable. We set the ref attribute of an empty div equal to this variable. Don’t forget to use curly braces.

  3. Then, we implement the scrollToBottom function, which is almost identical to the function from the previous example.

    We access the current property of the ref and the scrollIntoView() method. We add a smooth scrolling option here as well.

  4. Finally, we use the useEffect() hook to replace two lifecycle methods from before.

    The hook takes two arguments, and one is the function that will execute every time the component mounts. The second argument is an array of state variables to look out for.

    If the value of the messages state variable changes, useEffect() will also execute the function. This achieves the same result as using the componentDidUpdate() lifecycle hook.

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn

Related Article - React Scroll