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.