I want to change background color of navigation gradually with transition like this
Article.js
import React, { useRef, useEffect } from 'react'; import Grid from '@mui/material/Grid'; import { Link as RouterLink } from "react-router-dom"; import Typography from '@mui/material/Typography'; import Breadcrumbs from '@mui/material/Breadcrumbs'; import Link from '@mui/material/Link'; import './Article.css'; export default function Article() { const [isScrolling, setScrolling] = React.useState(false); useEffect(() => { function handleScroll() { if (window.scrollY < 10) { setScrolling(false); } else { setScrolling(true); } } window.addEventListener("scroll", handleScroll, { passive: true }); return () => { window.removeEventListener("scroll", handleScroll); }; }, [isScrolling]); function CreateBasicBreadcrumbs() { return ( <div role="presentation" className={`pop-up ${isScrolling && 'active'}`} > <Breadcrumbs aria-label="breadcrumb" sx={{ marginLeft: 2, }} > <Link underline="hover" color="inherit" component={RouterLink} to={'/'} > Home </Link> <Typography color="text.primary"> Articles </Typography> </Breadcrumbs> </div > ); } return ( <Grid container='true' direction='row' width='100%' sx={{ paddingTop: 5, backgroundColor: 'rgb(248, 249, 250)' }} onScroll={(e) => { console.log('scrolling') }} > <Grid item='true' xs={12} sm={12} md={12} lg={9} xl={7} sx={{ paddingLeft: 5, height: '2000px', }} > <CreateBasicBreadcrumbs /> </Grid> </Grid> ); }
Article.css
.pop-up { padding-bottom: 20px; border-top-left-radius: 10px; border-top-right-radius: 10px; position: sticky; top: 10px; transition: all 1s linear; } .pop-up.active { background-color: rgb(255, 255, 255); }
When I run these, class name ‘active’ is added to the [div] but its background color is changed quickly from rgb(248, 249, 250) to rgb(255, 255, 255).
I think this is because addEventListener changes isScrolling every scroll and rerenders the [div] element and its children. But I’m not sure.
Could you tell me what I am doing wrong?
Advertisement
Answer
You should not define a Component like CreateBasicBreadcrumbs
inside another component. If you do so, React thinks it is a different object on every render of Article
, so CreateBasicBreadcrumbs
will be unmounted before every rerender of Article
, losing its state.
Simply move its definition outside Article
, and pass isScrolling
as prop down to it.