Firstly i know theres many questions like this but i tried their answers too....
So lets get to the point: I want to add a class when i scroll in React... I tried to research some answers but none of them worked...
this is my app.js:
import React from "react";
import "./styles.css";
import { BrowserRouter as Router } from "react-router-dom";
export default class App extends React.Component {
componentDidMount() {
window.addEventListener("scroll", () => {
let activeClass = "";
if (window.scrollY === 0) {
activeClass = "top";
}
this.setState({ activeClass });
});
}
render() {
return (
<>
<Router>
<div className="something">
<div class="box"></div>
<div class={`box-menu ${this.activeClass}`}>something here</div>
<div class="content">
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
</div>
</div>
</Router>
</>
);
}
}
and this is my styles.css:
body {
margin: 0;
padding: 0;
}
.box {
height: 100px;
background-color: violet;
}
.box-menu {
position: fixed;
top: 100px;
bottom: 0;
left: 0;
width: 200px;
z-index: 5;
overflow-y: scroll;
}
/* THE MENU SHOULD GO TO THE TOP AND HAVE RED BACKGROUND COLOR */
.box-menu.top {
top: 0;
background: red;
}
.content {
margin-left: 200px;
padding-left: 28px;
background-color: aqua;
height: 100%;
}
I dont know why its not working... also i dont have any errors.
This is my code sandbox: https://codesandbox.io/s/inspiring-cloud-s27uv?file=/src/styles.css:0-430
Lastly if you guys need more details pls tell on the comments and ill do my best to provide it to you... Thank you in advance!!!
It doesn't update because you mislead local scoped variable with state. In the scope of event listener you set component state, but in your render function you try to refer to global variable which doesn't exist. In your case 'activeClass' is accessible in the scope of event listener only.
Other thing is that you should unlisten the scroll event listener in the componentWillUnmount() lifecycle method to prevent memory leaks. You should also you className attribute instead of class - this is one of the differences between standard HTML and JSX.
If you want to access your state in a way like you did you could destructure the activeClass from the this.state object:
render() {
const { activeClass } = this.state;
return (
...
);
}
Working example:
import React from "react";
import "./styles.css";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { activeClass: "" };
}
componentDidMount() {
window.addEventListener("scroll", () => {
let activeClass = "";
if (window.scrollY === 0) {
activeClass = "top";
}
this.setState({ activeClass });
});
}
componentWillUnmount() {
}
render() {
return (
<>
<div className="something">
<div className="box"></div>
<div className={`box-menu ${this.state.activeClass}`}>something here</div>
<div className="content">
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br /> SCROLLING
<br />
</div>
</div>
</>
);
}
}