How To Add A ClassName And Remove It OnScroll Event In React.JS?
I'm trying to make a Sticky Header that can change its background-color based on his position on the page. To do that, I'm trying to add a className "active" to my Styled Component "StyledHeader" that will appears when the scrollPositionY is above 400px and disappear when below.
In other words, what I want to do is something like this but using React.JS, JSX syntax and Styled Components.
Here's what I have for now:
import { Link } from '@reach/router';
import DuskLogo from '../images/dusk_logo.svg';
import {
StyledHeader,
StyledDuskLogo
} from '../styles/StyledHeader';
const Header = () => (
<StyledHeader>
<div className="header-content">
<Link to="/">
<StyledDuskLogo src={DuskLogo} alt="dusk-logo" />
</Link>
</div>
</StyledHeader>
)
export default Header;
Do you know a simple way to do it ?
Answer
add an event listener in your useEffect
. when you scroll down the value of window.scrollY
will increase such as 1, 2, ...100 .. (in px) and update your color
in useState
as per the window.scrollY
. try something like this
const StyledBody = window.styled.div`
background: lightgray;
height: 5000px;
`;
const StyledText = window.styled.h4`
text-align: center;
width: 250px;
margin: auto;
line-height: 40px;
`;
const StyledHeader = window.styled.div`
background-color: ${props => props.color};
width: 100%;
height: auto;
position: fixed;
top: 0;
left: 0;
right: 0px;
padding: 0;
z-index: 10000;
transition: all 1s ease-in-out;
`;
const Header = () => {
const [color, setColor] = React.useState("rgba(17, 42, 107, 0.7)");
const handleScroll = React.useCallback((event) => {
let scrollTop = window.scrollY;
//console.log(scrollTop ); //1,2,...100,...200...etc (in px)
if (scrollTop >= 20 && scrollTop < 50) {
setColor("yellow");
}
if (scrollTop >= 50 && scrollTop < 90) {
setColor("red");
}
if (scrollTop >= 90 && scrollTop < 120) {
setColor("green");
}
if (scrollTop >= 120 && scrollTop < 150) {
setColor("blue");
}
if (scrollTop >= 150 && scrollTop < 180) {
setColor("violet");
}
if (scrollTop >= 180 && scrollTop < 210) {
setColor("purple");
}
});
React.useEffect(() => {
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll, false);
};
}, []);
return (
<StyledBody>
<StyledHeader color={color}>
<StyledText>My background color changes</StyledText>
</StyledHeader>
</StyledBody>
);
};
export default Header;
here is a working demo ..change the code as per your need.demo
Edit: I have added styled-components for you. check it out and let me know whether it works for you. to know more about these hooks go to useEffect
and useCallback
Related Questions
- → Import statement and Babel
- → should I choose reactjs+f7 or f7+vue.js?
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → .tsx webpack compile fails: Unexpected token <
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → React Native with visual studio 2015 IDE
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
- → How do I determine if a new ReactJS session and/or Browser session has started?
- → Alt @decorators in React-Native
- → How to dynamically add class to parent div of focused input field?