【问题标题】:Reactjs - toggling class indipendently with right wayReactjs - 以正确的方式独立切换类
【发布时间】:2021-04-04 09:54:44
【问题描述】:

我正在尝试添加一个类并将其删除,它已经可用。我正在为每个元素分别做。但它总是指最后一个元素。这样做的正确方法是什么?

有没有简单而优雅的方法来做到这一点?

这是我的组件:

import React from "react";
import "./style.css";

export default class App extends React.Component {
  divRef;
  constructor(props){
    super(props)
    this.divRef = React.createRef();
  }
  toggleView = (e) => {
        e.preventDefault();
        if(this.divRef.current.classList.contains("active")){
          this.divRef.current.classList.remove("active"); //always refer div 2!?
          return;
        }
        this.divRef.current.classList.add("active");
    }
  render(){
     return (
    <div class="parent">
      <div ref={this.divRef}>
      1
      <a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
      </div>
      <div ref={this.divRef}>2
      <a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
      </div>
    </div>
  );
  }
}

Live demo

【问题讨论】:

    标签: reactjs tsx


    【解决方案1】:

    我会利用state 来实现这一点。不需要refs

    import React from "react";
    import "./style.css";
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          view1: false,
          view2: false
        };
      }
      toggleView = (e, view) => {
        e.preventDefault();
        this.setState({ [view]: !this.state[view] });
      };
      render() {
        return (
          <div class="parent">
            <div className={this.state.view1 ? "active" : ""}>
              1
              <a href="#" onClick={e => this.toggleView(e, "view1")}>
                toggle
              </a>
            </div>
            <div className={this.state.view2 ? "active" : ""}>
              2
              <a href="#" onClick={e => this.toggleView(e, "view2")}>
                toggle
              </a>
            </div>
          </div>
        );
      }
    }
    

    Live Demo

    编辑: 在这里,我展示了当我们有很多项目时这种方法如何扩展

    import React from "react";
    import "./style.css";
    
    const NUM_ITEMS = 20;
    const items = Array.from({ length: NUM_ITEMS }).map((_, idx) => ({
      title: "title" + idx,
      active: false
    }));
    
    const Item = ({ active, title, onToggle }) => (
      <div className={active ? "active" : ""}>
        {title}
        <a
          href="#"
          onClick={e => {
            e.preventDefault();
            onToggle();
          }}
        >
          toggle
        </a>
      </div>
    );
    
    export default class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          items
        };
      }
      toggleView = idx => {
        const items = [...this.state.items];
        items[idx] = { ...items[idx], active: !items[idx].active };
        this.setState({ items });
      };
      render() {
        return (
          <div class="parent">
            {this.state.items.map((item, idx) => (
              <Item
                key={item.title}
                active={item.active}
                title={item.title}
                onToggle={() => this.toggleView(idx)}
              />
            ))}
          </div>
        );
      }
    }
    

    Demo

    【讨论】:

    • 如何添加现有类?对我来说它不起作用:&lt;div className={info + ${this.state.view1 ? '活动' : ''}}&gt;
    • 有一个小型库可以帮助解决这个问题:npmjs.com/package/classnames
    【解决方案2】:

    我明白了:

    import React from "react";
    import "./style.css";
    
    export default class App extends React.Component {
      divRef;
      constructor(props){
        super(props)
        this.divRef = React.createRef();
      }
      toggleView = (e) => {
            e.preventDefault();
            const element = e.currentTarget.parentElement.classList;
            if(element.contains("active")){
              element.remove("active");
              return;
            }
            element.add("active");
        }
      render(){
         return (
        <div class="parent">
          <div ref={this.divRef}>
          1
          <a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
          </div>
          <div ref={this.divRef}>2
          <a href="#" onClick={(e) => this.toggleView(e)}>toggle</a>
          </div>
        </div>
      );
      }
    }
    

    如果有人发现,这不是正确的方法,请告诉我

    【讨论】:

    • 请查看我的答案以获得更简单的解决方案
    • 问题是,如果我有 20 个元素,我需要在状态中添加所有 20 个元素。它看起来很不干净,是不是?
    • 实际上没有,因为您在这里缺少 React 的一个基本部分 - 它是状态驱动的。我会更新我的答案来说明这一点
    • @thedude 完全正确,他的回答应该被接受。
    【解决方案3】:

    也许你可以通过使用两个单独的参考来做到这一点,这里是演示:https://stackblitz.com/edit/react-b1wa4f?file=src%2FApp.js

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-08-24
      • 2019-04-02
      相关资源
      最近更新 更多