如何在滚动 ReactJS 上添加 class

How to add class on scroll ReactJS

首先我知道有很多这样的问题,但我也尝试了他们的答案....

所以让我们进入正题:当我在 React 中滚动时,我想添加一个 class...我试图研究一些答案,但其中 none 有效...

这是我的 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>
      </>
    );
  }
}

这是我的 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%;
}

我不知道为什么它不起作用...我也没有任何错误。

这是我的代码沙箱:https://codesandbox.io/s/inspiring-cloud-s27uv?file=/src/styles.css:0-430

最后,如果你们需要更多细节,请在评论中告诉我,我会尽力提供给你们...提前谢谢你们!!!

缺少两件事:

首先设置初始状态(使组件有状态)

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {activeClass: 'top'};
  }
  ...
}

然后从状态对象访问状态:

<div className={`box-menu ${this.state.activeClass}`}>something here</div>

它不会更新,因为您用状​​态误导了局部作用域变量。在事件侦听器的范围内,您设置组件状态,但在您的渲染函数中,您尝试引用不存在的全局变量。在你的情况下 'activeClass' 只能在事件侦听器的范围内访问。

另一件事是您应该在 componentWillUnmount() 生命周期方法中取消监听滚动事件监听器以防止内存泄漏。 您还应该 className 属性而不是 class - 这是标准 HTML 和 JSX 之间的区别之一。

如果您想像以前一样访问您的状态,您可以从 this.state 对象中解构 activeClass:

 render() {
  const { activeClass } = this.state;
  return (
    ...
  );
}

工作示例:

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>
      </>
    );
  }
}

您的代码中有几个问题。

您需要设置一个初始状态

 constructor(props) {
  super(props);
  this.state = {activeClass: 'top'};
}

在jsx中你需要使用

<div className={`box-menu ${this.state.activeClass}`}>

此外,您的 css

中缺少一个 space
.box-menu .top {
  top: 0;
  background: red;
}