Reactjs - 以正确的方式独立切换 class

Reactjs - toggling class indipendently with right way

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

有什么简单而优雅的方法可以做到这一点吗?

这是我的组件:

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

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

我会利用 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

我明白了:

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

如果有人发现这种方法不对,请告诉我