0

I have one question, how to use multiple toggle class

Please check my example below

I want to click <TaxItem /> and add some class to that element, and the second click to remove that class

import React, { Component } from "react";
import TaxItem from "./TaxItems/"
import Pentagon from "../../../assets/images/pentagon.png"

class Taxs extends Component {
  constructor(props) {
    super(props)
    this.state = {
      taxStatus: false
    }
    this.handleTaxStatus = this.handleTaxStatus.bind(this);
  }

  handleTaxStatus(element) {
    console.log('sdasa', element)
  }

  render() {
    return (
      <div className="taxs">
        <TaxItem
          image={Pentagon}
          name='Item 1'
          taxStatus={false}
          handleTaxStatus={this.handleTaxStatus(this)}
        />
        <TaxItem
          image={Pentagon}
          name='Item 2'
          taxStatus={false}
          handleTaxStatus={this.handleTaxStatus(this)}
        />
      </div>
    )
  }
}

export default Taxs

And here you can check button where I have onClick:

import React, { Component } from "react";

class TaxItem extends Component {
  render() {
    return (
      <div className="tax-item" onClick={this.props.handleTaxStatus}>
        <div className={this.props.taxStatus ? 'checked on' : 'checked'}><i className="icon icon-check"></i></div>
        <img src={this.props.image} alt="Pentagon" />
        <p>{this.props.name}</p>
      </div>
    )
  }
}

export default TaxItem

How I can use THIS, something like jQuery.

Tholle
  • 108,070
  • 19
  • 198
  • 189
Boris Civcic
  • 110
  • 1
  • 9
  • Possible duplicate of [Add/Remove class to parent DOM element React js](https://stackoverflow.com/questions/52364174/add-remove-class-to-parent-dom-element-react-js) – Bhojendra Rauniyar Mar 12 '19 at 15:59
  • Yes, but I have one button to click – Boris Civcic Mar 12 '19 at 16:02
  • Hello!.. First, you should fix your example by creating a functional one, instead of just putting the two React Components implementation.. :) Anyways, if you want to add the class to just the clicked `TaxItem`, then you need a `taxStatus` property for each one of them, and pass a different `taxStatus` to each `TaxItem`. Using "this" would lead to modifying the DOM directly, which in this case, can avoided – Jolly Mar 12 '19 at 16:03
  • @BorisCivcic The ref does. Just try at your end and ask again if you're not able to solve. – Bhojendra Rauniyar Mar 12 '19 at 16:03

1 Answers1

0

As I said in the comment, I would suggest you to not use "THIS", which would mean use the refs, because it would lead to edit the DOM directly, which in React should be avoided when you can.

Instead, you could use an array of taxStatus property, one for each TaxItem, and using them as toggle, something like in the following:

class TaxItem extends React.Component {
    localHandleClick = (_) => {
            this.props.handleClick(this.props.taxStatusIndex);
        };
    
    render() {
        const {taxStatus, handleClick} = this.props;
        
        return (
            <div
                className={"button" + (taxStatus ? " checked" : " not-checked")}
                onClick={this.localHandleClick} />
        );
    }
}

class Taxs extends React.Component {
    constructor(props) {
        super(props);
        
        const taxItemCounter = props.num;
        
        this.state = {
            taxesStatus: new Array(taxItemCounter).fill(false)
        }
    }
    
    handleClick = (i) => {
        const taxesStatus = this.state.taxesStatus;
        taxesStatus[i] = !taxesStatus[i];
        
        this.setState({taxesStatus});
    }
    
    render() {
        return (
            <div>
                {
                    this.state.taxesStatus.map((status, index) => 
                        <TaxItem
                            key={index}
                            taxStatusIndex={index}
                            handleClick={this.handleClick}
                            taxStatus={status} />
                )}
            </div>
        );
    }
}

ReactDOM.render(<Taxs num={3} />, document.getElementById('root'));
@import url(https://fonts.googleapis.com/css?family=Montserrat);

body {
    font-family: 'Montserrat', sans-serif;
}

.button {
    width: 100px;
    height: 25px;
    background: red;
    margin: 10px;
    cursor: pointer;
}

.button.checked {
    background: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id='root'></div>

Anyways, if you DO want to use "THIS" (which again, would mean using the refs), I can provide you an example.

Jolly
  • 1,678
  • 2
  • 18
  • 37
  • Yes, but I don't know how much I will have TaxItem. I need to add for each [0],[1]? – Boris Civcic Mar 12 '19 at 16:22
  • I've edited the snippet: sooner or later you will now how many TaxItem you will have (probably because of a prop that you pass to `Taxs` Component. In the snippet, I pass a prop called `num`, and based on that, I create an array of desired length, and also the `render()` changes, as you can see, rendering `num` `TaxItem` – Jolly Mar 12 '19 at 16:29
  • I've edited again the snippet to avoid arrow function inside the `render()` method – Jolly Mar 12 '19 at 16:33
  • Thank you, that's it! :) – Boris Civcic Mar 12 '19 at 17:08
  • You're welcome! Though, the solution might not be the best. One question: is it mandatory that `Taxs` Component knows the state of the button? Because you could have `taxesStatus` directly inside the `TaxItem` Component – Jolly Mar 12 '19 at 19:13