How to make a scroll to the top button in React
Back

How to make a scroll to the top button in React

Requirements

  • Code Editor
  • React.js
  • or

Introduction

It is frustrating when you are scrolling through a page and when you want to go back to the top and you don't have the ability to do it quickly, I mean, if the developer feel the pain, the user mind as well close the page altogether 😂. It really hurts the user experience and the problem should be addressed.

So lets code a little component to address this problem.

Lets code

Firstly lets make our base code for the component:

import React from "react"; const ScrollButton = () => { return <h1>Hello World</h1>; }; export default ScrollButton;

Ok, now we're gonna need the button itself and an icon from an excellent little library called :

Add the library:

yarn add react-icons

Or:

npm i react-icons

Then add it in the component:

import React from "react"; import { BsArrowUp } from "react-icons/bs"; const ScrollButton = () => { return ( <button> <BsArrowUp /> </button> ); }; export default ScrollButton;

Now we have to build our helper functions. Starting with the function that will make the scroll to the top:

import React from "react"; import { BsArrowUp } from "react-icons/bs"; const ScrollButton = () => { const scrollOnClick = () => { window.scrollTo(0, 0); }; return ( <button onClick={scrollOnClick}> <BsArrowUp /> </button> ); }; export default ScrollButton;

The method scrolls the document to the specified coordinates, so (0, 0) should scroll to the top of the page.

Now we need a helper function so we know where we are positioned on the screen:

const handlePosition = () => { if (window.scrollY >= 200) { // do something } else { // do something } };

The function has to store the information on the state so:

const [scrolled, setScrolled] = React.useState(false); const handlePosition = () => { if (window.scrollY >= 200) { setScrolled(true); } else { setScrolled(false); } };

The property of the window interface returns the number of pixels that the document is currently scrolled vertically. So by comparing it in the conditional statement by 200 we should find out if the page is scrolled beyond 200 pixels vertically.

Now we are gonna need a hook to listen to the scroll event on page load:

const handlePosition = () => { if (window.scrollY >= 200) { setScrolled(true); } else { setScrolled(false); } }; React.useEffect(() => { window.addEventListener("scroll", handlePosition); return function cleanup() { window.removeEventListener("scroll", handlePosition); }; }, []);

The method attaches an event handler to the specified element . Then to clean up the hook, you need to . The partial code should be this:

import React from "react"; import { BsArrowUp } from "react-icons/bs"; const ScrollButton = () => { const [scrolled, setScrolled] = React.useState(false); const scrollOnClick = () => { window.scrollTo(0, 0); }; const handlePosition = () => { if (window.scrollY >= 200) { setScrolled(true); } else { setScrolled(false); } }; React.useEffect(() => { window.addEventListener("scroll", handlePosition); return function cleanup() { window.removeEventListener("scroll", handlePosition); }; }, []); return ( <button onClick={scrollOnClick}> <BsArrowUp /> </button> ); }; export default ScrollButton;

Styling

Now that we coded the "crude" component, we can style it a little bit.

Add :

yarn add styled-components

Or:

npm i styled-components

Create the button and icon components:

import React from "react"; import { BsArrowUp } from "react-icons/bs"; import styled from "styled-components"; const StyledButton = styled.button` position: fixed; bottom: 10vh; right: 6vw; cursor: pointer; background: #333; border: none; height: 30px; width: 30px; border-radius: 50%; align-items: center; justify-content: center; `; const StyledIcon = styled(BsArrowUp)` font-size: 1.5rem; color: #fff; `;

After creating the we can apply the scroll helper functions to make the button only appear when the page is scrolled down:

First, we need to attach the state we created before, , on the styled button:

return ( <StyledButton onClick={scrollOnClick} scrolled={scrolled}> <StyledIcon /> </StyledButton> ); };

Then we use the state variable on the button component:

const StyledButton = styled.button` display: ${({ scrolled }) => (scrolled ? "flex" : "none")}; z-index: 999; position: fixed; bottom: 10vh; right: 6vw; cursor: pointer; background: #333; border: none; height: 30px; width: 30px; border-radius: 50%; align-items: center; justify-content: center; `;

Conclusion

Alright! The live example should be in front of you right now, as this blog has a version very close to this button that we coded.

The whole code should be this:

import React from "react"; import { BsArrowUp } from "react-icons/bs"; import styled from "styled-components"; const StyledButton = styled.button` display: ${({ scrolled }) => (scrolled ? "flex" : "none")}; z-index: 999; position: fixed; bottom: 10vh; right: 6vw; cursor: pointer; background: #333; border: none; height: 30px; width: 30px; border-radius: 50%; align-items: center; justify-content: center; `; const StyledIcon = styled(BsArrowUp)` font-size: 1.5rem; color: #fff; `; const ScrollButton = () => { const [scrolled, setScrolled] = React.useState(false); const scrollOnClick = () => { window.scrollTo(0, 0); }; const handlePosition = () => { if (window.scrollY >= 200) { setScrolled(true); } else { setScrolled(false); } }; React.useEffect(() => { window.addEventListener("scroll", handlePosition); return function cleanup() { window.removeEventListener("scroll", handlePosition); }; }, []); return ( <StyledButton onClick={scrollOnClick} scrolled={scrolled}> <StyledIcon /> </StyledButton> ); }; export default ScrollButton;

Additional Resources

â“’ 2025 Andrei T.F.
with Next.js