Hide floating button after scroll to down in React.js

ยท

2 min read

I was working on a project that needed to move the user to the bottom of the page when the screen was small. Imported a button with absolute position, but it did not disappear at the bottom and you could see two same buttons there. The user had to see the button all over the page except at the end of that.
Here is my code:

// src/App.tsx
import {useEffect, useRef, useState} from "react";
import {Box, Button, Paper, Stack, Typography} from "@mui/material";

const App = () => {
    const containerRef = useRef<HTMLDivElement>(null)
    const ref = useRef<HTMLElement>(null)
    const [showBtn, setShowBtn] = useState<boolean>(true)

    const isBottom = (el: HTMLElement) => {
        return el.getBoundingClientRect().bottom <= window.innerHeight;
    }

    const trackScrolling = () => {
        const wrappedElement = document.getElementById('container');
        if (isBottom(wrappedElement)) {
            setShowBtn(false)
        } else {
            setShowBtn(true)
        }
    };

    useEffect(() => {
        document.addEventListener('scroll', trackScrolling)
        return () =>
            document.removeEventListener('scroll', trackScrolling);
    }, [trackScrolling]);

    return (
        <Box
            sx={{
                position: 'relative',
                mx: 25,
                mt: 2,
                mb: 15,
                textAlign: 'justify'
            }}
            ref={containerRef}
            id={'container'}>
            {
                [...new Array(25)]
                    .map(() => `Lorem ipsum dolor sit amet,
                               consectetur adipisicing elit.
                               Aliquid consequuntur dolorem eos expedita 
                               impedit ipsum maiores nulla,
                               odio officiis optio quas quod reiciendis,
                               saepe sunt tenetur unde voluptas
                               voluptate voluptatibus?`,
                    )
                    .join('\n')
            }
            <Paper elevation={3} sx={{p: 2, mt: 15}} ref={ref}>
                <Stack direction={'column'} alignItems={'center'}>
                    <Typography>I want to see here, need the float button disappear!</Typography>
                    <Button
                        variant={'contained'}
                        size={'small'}
                        onClick={() => {
                            alert('Do something')
                        }}
                    >Scroll to down</Button>
                </Stack>
            </Paper>
            <Stack alignItems={'center'} sx={{
                position: 'sticky',
                bottom: 10,
                display: showBtn ? 'normal' : 'none'
            }}>
                <Button
                    variant={'contained'}
                    size={'small'}
                    onClick={() => {
                        ref.current?.scrollIntoView({behavior: 'smooth'})
                    }}
                >Scroll to down</Button>
            </Stack>
        </Box>
    );
}
export default App

Let me explain what I did:
- create a react project with Parcel. (Will write a blog about Parcel & React soon ๐Ÿ˜‰)
- set an id and ref for the container element
- set a ref for that element I want to scroll to
- calculate the bottom of the container element into isBottom() function and set value to the state into trackScrolling()
- and finally, update the state in useEffect hook with listening to scroll.

Hope this article will help someone one day.

Source code: https://github.com/hamitmohamadi/react-hide-float-button-on-scroll-down.git

ย