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.

4
  • Possible duplicate of Add/Remove class to parent DOM element React js Commented Mar 12, 2019 at 15:59
  • Yes, but I have one button to click Commented Mar 12, 2019 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 Commented Mar 12, 2019 at 16:03
  • @BorisCivcic The ref does. Just try at your end and ask again if you're not able to solve. Commented Mar 12, 2019 at 16:03

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Yes, but I don't know how much I will have TaxItem. I need to add for each [0],[1]?
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
I've edited again the snippet to avoid arrow function inside the render() method
Thank you, that's it! :)
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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.