How to Scroll to Top, Bottom or Any Section in React with a Button Component

Introduction

The "scroll-to-top" feature is an excellent addition to any website that forces visitors to scroll a long distance before reaching the bottom of the page, since it becomes quite annoying to return back to the top.

By extension, scrolling to the bottom or any particular point or section allows you to navigate a user in a seamless experience for Single-Page Applications (SPAs).

In this hands-on guide, we will learn how to make a React button that allows users to scroll to the top, bottom or any section with React. We'll utilize React hooks and make this a reusable component. At the conclusion of this article, we'll look at how to do it with the react-scroll-to-top library.

Note: The source code is available in our GitHub repository, and to see a live demo of the application, visit this Vercel App.

Using React and React Hooks

For simple functionality like this, you can easily code a solution from scratch, rather than installing a library. Creating functionality like this from scratch allows for more customization and an appreciation for what libraries abstract away!

Getting Started

We'll be making a separate component, producing a reusable piece of code that can be spread out between your projects. We'll additionally be using an arrow icon from react-icons for this guide, though, any icon that works for you will work just as well.

Installing react-icons

To use react-icons, you have to install the module. You can install react-icons with:

$ npm i react-icons

Scroll to Top in React

Let's import the library and the icon itself, and set them up as a component:

import React from 'react';
import { FaAngleUp } from 'react-icons/fa';

import './index.css';

const ScrollToTop = () => {
    return (
        <div className="top-to-btm">
            <FaAngleUp className="icon-position icon-style" />
        </div>
    );
};
export default ScrollToTop;

Let's also apply some style to the icon and add a movement animation in index.css:

.top-to-btm{
  position: relative;
}
.icon-position{
  position: fixed;
  bottom: 40px;
  right: 25px;
  z-index: 20;
}
.icon-style{
  background-color: #551B54;
  border: 2px solid #fff;
  border-radius: 50%;
  height: 50px;
  width: 50px;
  color: #fff;
  cursor: pointer;
  animation: movebtn 3s ease-in-out infinite;
  transition: all .5s ease-in-out;
}
.icon-style:hover{
  animation: none;
  background: #fff;
  color: #551B54;
  border: 2px solid #551B54;
}
@keyframes movebtn {
  0%{
    transform: translateY(0px);
  }
  25%{
    transform: translateY(20px);
  }
  50%{
    transform: translateY(0px);
  }
  75%{
    transform: translateY(-20px);
  }
  100%{
    transform: translateY(0px);
  }
}

Great! Now we can implement the logic that takes the user back up to the top of the page.

Implementing the Logic

We'll be using the useState() and useEffect() hooks to allow us to develop the functionality easily and quickly.

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

The next step is to create a state and set it to false by default; this state will control the visibility of the "scroll-to-top" button, since we only want the button to appear after the user has scrolled down a bit and to vanish after the user has scrolled all the way to the top:

const [showTopBtn, setShowTopBtn] = useState(false);

At this point, we'll utilize the useEffect() hook to build the logic that determines when we want the button to appear and when we want it to disappear.

Note: The Effect Hook is active by default after the initial render and each time the state is updated. It is used to conduct an effect whenever the state changes, as the name implies.

Let's set the state to true after the user has scrolled down by 400 pixels:

useEffect(() => {
    window.addEventListener('scroll', () => {
        if (window.scrollY > 400) {
            setShowTopBtn(true);
        } else {
            setShowTopBtn(false);
        }
    });
}, []);

We added an EventListener to the window to listen for a scroll and then run a function when the conditional within the listener returns true. If the vertical scroll position is more than 400 (as determined by you), the function sets the showTopBtn state to true; otherwise, it sets it to false. Remember that this will constantly run when you scroll through the webpage, and will thus update the button to stop showing when someone's scrolled back up to the top of the page.

The final functionality we'll want to implement is handling the click event! Once the user clicks on the button, we'll want to scroll them back to the top. Thankfully - the window object has a dedicated scrollTo() method exactly for this! Let's wrap it around with a function we'll call when a user clicks the button:

const goToTop = () => {
    window.scrollTo({
        top: 0,
        behavior: 'smooth',
    });
};

Note: window.scrollTo() also accepts a behavior parameter which is used to specify whether the scrolling should be animated smoothly (smooth), or happen instantly in a single jump (auto, the default value).

Finally, let's add an onclick() listener to the button in our markup, hooking it up to the goToTop() method:

import React, { useState, useEffect } from "react";
import { FaAngleUp } from "react-icons/fa";

import "./index.css";

const ScrollToTop = () => {
    const [showTopBtn, setShowTopBtn] = useState(false);
    useEffect(() => {
        window.addEventListener("scroll", () => {
            if (window.scrollY > 400) {
                setShowTopBtn(true);
            } else {
                setShowTopBtn(false);
            }
        });
    }, []);
    const goToTop = () => {
        window.scrollTo({
            top: 0,
            behavior: "smooth",
        });
    };
    return (
        <div className="top-to-btm">
            {" "}
            {showTopBtn && (
                <FaAngleUp
                    className="icon-position icon-style"
                    onClick={goToTop}
                />
            )}{" "}
        </div>
    );
};
export default ScrollToTop;

That's it! The component can now be imported into a new page and used. In the App.js file, let's import it:

import ScrollToTop from './ScrollToTop';

function App() {
    return (
        <div className="App">
            <ScrollToTop />
            <div className="section section1"></div>
            <div className="section section2"></div>
            <div className="section section3"></div>
            <div className="section section4"></div>
            <div className="section section5"></div>
        </div>
    );
}

export default App;
Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Note: For styling this page, refer to our GitHub repository..

Using the react-scroll-to-top Library

The react-scroll-to-top library is a lightweight, customizable button component that scrolls to the top of the page when clicked. This component is analogous to our own, but you don't have to code it up yourself.

Naturally, it only appears once you've scrolled down enough that it makes sense for it to appear.

Installing react-scroll-to-top

Run this command in your terminal:

$ npm i react-scroll-to-top

Scroll to Top with react-scroll-to-top

To use the component, we import react-scroll-to-top and use it as we've used our own:

Import and then include <ScrollToTop /> anywhere in your render/return function:

import ScrollToTop from "react-scroll-to-top";

function App() {
    return (
        <div className="App">
            <ScrollToTop />
            <div className="section section1"></div>
            <div className="section section2"></div>
            <div className="section section3"></div>
            <div className="section section4"></div>
            <div className="section section5"></div>
        </div>
    );
}

export default App;

The library is customizable as well! There's a fair bit of props you can tweak for different effects.

This has so many props, and they are all listed below with their description and the type of data they take in:

Prop Type Description Default
smooth boolean Whether to use smooth scrolling* false
top number Height after page scroll to be visible 20
color string The SVG icon fill color "black"
svgPath string The SVG icon path d attribute An arrow path
width string The SVG icon width "28"
height string The SVG icon height "28"
viewBox string The SVG icon viewBox attribute "0 0 256 256"
component any Component to override SVG icon. See examples
style Object Object to add/override styling
className string Classname to completely override styling

Scroll to Bottom

The scroll-to-bottom feature in React works similarly to the scroll-to-top - we define a function, that on a button press, scrolls the user to a set point. This time, the point won't be the top - it'll be the bottom:

const scrollToBottom = () => {
  window.scrollTo({
    top: document.documentElement.scrollHeight,
    behavior: 'smooth',
  });
};

We set the top property to the height of the entire page, as procured from the document. This will ensure that we get scrolled down to the pixel-height below the entire page - or rather, to the bottom of the page.

The next step would be to include the onclick() method in our markup for the button:

<div className="link btn" onClick={scrollToBottom}>
  Scroll to bottom <MdArrowDropDownCircle />
</div>

Scroll To a Particular Section with React

Scrolling to a certain section is really popular with single-page websites, because instead of routing a user to a different page for common pages such as "About Us" and "Contact" - you can just scroll them down to the relevant section on that page. This is a popular approach when telling stories with pages, where a user is expected to scroll down anyway, but can skip to a certain section as well.

Again - this is essentially what we've been doing. This time though, we'll scroll to a given element.

Implementing the Logic

We will use the useRef() hook - it is a built-in React hook that accepts one argument as its initial value and returns a reference. The reference has an interesting and useful property called current. The useRef() hook is similar to Vanilla JavaScript's getElementById().

The first step is to import useRef() and then create a ref (reference) to the part we want to scroll to:

import { useRef } from react;

const aboutSection = useRef(null);

The next step would be to add the ref we declared to the section we wish to scroll to:

<div className="section section2" ref={aboutSection}>
    <h2>About Us</h2>
</div>

Now, we scroll to the current reference, and offset it to the top, so as to put the top of the element at the top of the screen rather than on the bottom of it:

const scrollDown = () => {
  window.scrollTo({
    top: aboutSection.current.offsetTop,
    behavior: 'smooth',
  });
};

At this point, we have successfully implemented all the logic necessary to assist us in scrolling to a specified region of our homepage using react. Next, we'll add the onclick() method to the button in our markup:

<li className="link" onClick={scrollDown}>
  About Us
</li>

Making our Code Reusable

Nav bars typically have several links leading to several sections. Repeated actions call for generalization between instances! We can make the logic reusable this way:

const scrollDown = (ref) => {
  window.scrollTo({
    top: ref.current.offsetTop,
    behavior: 'smooth',
  });
};

In the code above, we are passing the ref's value from the function that is being triggered in the individual's button.

The navigation bar on your page could look something along the lines of:

<div className="section section1">
    <div className="link btn">
        Scroll to bottom <MdArrowDropDownCircle />
    </div>
    <ul className="nav-links">
        <li className="link" onClick={() => scrollDown(aboutSection)}>
        About Us
        </li>
    <li className="link" onClick={() => scrollDown(servcesSection)}>
        Services
    </li>
    <li className="link" onClick={() => scrollDown(contactSection)}>
        Contact
      </li>
    </ul>
</div>

<div className="section section2" ref={aboutSection}>
    <h2>About Us</h2>
</div>
<div className="section section3" ref={servcesSection}>
    <h2>Services</h2>
</div>
<div className="section section4" ref={contactSection}>
    <h2>Contact</h2>
</div>

Conclusion

In this guide, we have learned how to create a reusable component, from scratch, to perform the scroll-to-top operation easily. This component is easily transferable between projects! Just transfer the associated files and import it into a new page. Finally - we've taken a look at a popular library that takes care of this for us, as well as the props associated with customizing it.

The live demo for the application can be found here.

Last Updated: May 24th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Joel OlawanleAuthor

Frontend Developer & Technical Writer

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms