Aleksander Sadaj
Aleksander Sadaj

Reputation: 194

How do I assign CSS class based on state variable's value in ReactJS

Im coding up a project in ReactJS. Ive got some divs that can be clicked by user. By default every div's background color should be set to green, but after the click it should become red (meaning that this specific div has been already clicked and further clicking on it won't make any difference). My idea for setting the CSS class is that inside className I've got a ternary if statement based on corresponding value from the array. The solution I've presented doesn't do anything, no errors are popping up. How can I achieve my goal?

Code:

var style = require('./board.css');

var React = require('react');

class board extends React.Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.state = {
            fieldClicksArray: [
                false, false, false, 
                false, false, false, 
                false, false, false
            ]
        }
    }

    handleClick(index) {
      if (this.state.fieldClicksArray[index] === false) {
          this.state.fieldClicksArray[index] = true;
    }

    render () {
        return (
            <div className="parent">
                    <div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick={() => this.handleClick(0)}>1</div>
            </div>//parent
        )//return
    }//render
}//class

export default board;

The CSS:

.red {
    background-color: red;
}

.green {
    background-color: green;
}

Upvotes: 3

Views: 3512

Answers (2)

Anurag Awasthi
Anurag Awasthi

Reputation: 6223

class Board extends React.Component {
    constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
        this.state = {
            fieldClicksArray: [
                false, false, false, 
                false, false, false, 
                false, false, false
            ]
        }
    }

    handleClick(index) {
      if (this.state.fieldClicksArray[index] === false) {
          var newArray = this.state.fieldClicksArray;
          newArray[index] = true;

          this.setState({
              fieldClicksArray: newArray
           })
           }
    }

    render(){
        return(
            <div className="parent">
                <div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick= {()=>this.handleClick(0)}>1</div>
        </div>//parent
        )//return
    }//render
}//class

ReactDOM.render(<Board />, document.getElementById("app"))
.red {
    background-color: red;
}

.green {
    background-color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

this.state.fieldClicksArray[index] = true; wont perform anything. you need to call this.setState to change the state of your component.

handleClick(index) {
      if (this.state.fieldClicksArray[index] === false) {
          var newArray = this.state.fieldClicksArray;
          newArray[index] === false;

          this.setState({
              fieldClicksArray: newArray
           })
    }

Also to use setState method in your click handler, you'll need to bind your function to the component,

 render () {
        return (
            <div className="parent">
                <div className={this.state.fieldClicksArray[0] ? 'red' : 'green'} onClick= {()=>this.handleClick(0)}>1</div>
        </div>//parent
        )//return
    }

Upvotes: 1

Dan Abramov
Dan Abramov

Reputation: 268225

You need to use setState(). And clone the array so that you don't mutate the previous state. Finally, it is better to use the functional form of setState() when your next state is calculated from previous state.

handleClick(index) {
  this.setState((prevState) => {
    // make a copy
    let fieldClicksArray = prevState.fieldClicksArray.slice();
    // change one item
    fieldsClickArray[index] = true;
    // return next state to be merged
    return { fieldsClickArray };
  });
}

Read more: https://facebook.github.io/react/docs/state-and-lifecycle.html#using-state-correctly

Hope this helps!

Upvotes: 4

Related Questions