React JS - I need a button color to change onClick but cannot determine how to properly set and change State for that component

React JS - I need a button color to change onClick but cannot determine how to properly set and change State for that component
0

#1

When the user clicks a button, I need the user to see that the button has been clicked.

The approach I am taking is to update the state for that component so that the button is re-rendered with a different background color. How is this actually done?

The CodePen for this is here

Here is the code:

 var ActionBox = React.createClass({ 

 showMyNumbers: function(){
  if(this.props.pears === "default")
    {console.log("This is in the default configuration")}
    else{console.log("This is in some other configuration")}
  },

  render: function() {
   return(
     <div id="actionBox" onClick={this.showMyNumbers}>
       </div>
   );
 }, 
});

var ApplicationGrid = React.createClass({  

  render: function() {
   var row = [];
   for(var j=0; j<30; j++){
     for(var i=0; i<30; i++){
       row.push(<ActionBox myRowNumber={j} myColumnNumber={i} pears = {this.props.oranges}/>);
      }
   }
    return(
     <div id="applicationGrid">
        {row}
      </div>
    );
  }, 
});

var ButtonsAndGrid = React.createClass({ 



  getInitialState: function() {
    var defaultcolor1 = document.getElementById(btn1).style.backgroundColor;
    return {
      btn1Bckground: defaultcolor1,
    };
  },

  changecolor() {
        this.setState({
      btn1Bckground: "lightblue"
   });
    },

  componentDidMount() {
      this.refs.button1.addEventListener('click', this.changecolor);
     
   },


  render: function() {

    return(
   <div>
   <div id="buttonsDiv">
  
     <button type="button" ref="button1" className="normalBtn" id="btn1" onClick={this.props.plethora} >This works</button>
  
     </div>
   <ApplicationGrid oranges = {this.props.apples} />
    </div>
    );
 }, 
});

var MyApp = React.createClass({  


 getInitialState: function() {

   return {
     startingConfiguration: "default",
    };
  },


 doSomething: function(evt) {
   this.setState({
     startingConfiguration: "other"
    });
  },

 render: function() {
  return(
    <div id="mainDiv" >
  <h1> Game of Life! </h1>
    <ButtonsAndGrid apples={this.state.startingConfiguration} plethora={this.doSomething}/> <Footer />
    </div>
    );
  }, 
});

var Footer = React.createClass({
  render() {
   return (
    <footer>
      <div id="containerfooter">
          <p>Written by <a href="http://codepen.io/profaneVoodoo/full/dXBJzN/">John Gillespie</a> for FreeCodeCamp Campers (and also to impress my kids). Happy Coding!</p>
        </div>
      </footer>
    );
  }
  });

ReactDOM.render(
  <MyApp />  ,
  document.getElementById('GoL')
);

#2

here I have made a very very simple illustration.hope it helps-

Since I am unable to post the codepen link for whatever reason-here is the code

`

var Button = React.createClass({
  getInitialState: function() {
    return {
      bgColor: 'red'
    }
    
  },
  
  handleClick: function() {
    this.setState({
      bgColor: 'blue'
    })
  },
  
  render : function() {
    return (
      <div>
        <button 
          onClick={this.handleClick} 
          style={{backgroundColor:this.state.bgColor}}>Button</button>
      </div>
    )
  }
});

ReactDOM.render(
  <Button />,
    document.getElementById('button')
);

`


#3

@Faizahmadfaiz’s answer should work just fine. Here is also another way that I’ve used, basically setting CSS conditionally in the render function based on the current state. In the render function something like:

`

render : function() {
    return (

        // you can have the button's handleClick function
        //change its status to clicked from unclicked in the state
        //so then here you can do this:

	var yourBtn = this.state.buttonStatus;

	// so default is this style:
	var btnStyle = {
		backgroundColor: 'gray'
	}

	// but if it is clicked you will the style this way:
	if (yourBtn == 'clicked') {
		btnStyle = {
			backgroundColor: 'red'
		}
	}

  <div>
    <button 
      onClick={this.handleClick} 
      style={btnStyle}>Button</button>
  </div>
)}

`


#4

Nice, that works. And if I need the button click to fire multiple functions, I just add those to the handleClick function.

var ButtonsAndGrid = React.createClass({ 

  getInitialState: function() {
    return {
      bgColor: 'red'
    }

  },

  handleClick: function() {
    this.props.plethora()
    this.setState({
      bgColor: 'blue'
    })
  },

  render: function() {

    return(
   <div>
    <div id="buttonsDiv">
  
     <button type="button" ref="button1" className="normalBtn" id="btn1" onClick={this.handleClick} style={{backgroundColor:this.state.bgColor}}>This works</button>

#5

Yes…exactly!You can put everything in handle function which you want to do after click.


#6

Glad you got it working, but now I’m confused as to why this works without .bind(this)-ing the handleClick function? I just completed the Leaderboard assignment, and none of my functions that needed a reference for this worked at all without binding them?

Is this a difference between the es6 class Component extends React.Component and the var Component = React.createClass syntax?


#7

yes! http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes
see step-3 in above link


#8

Thanks @Faizahmadfaiz ! That is an extremely helpful link


#9

@Tattomoosa No problem! :slight_smile:


#10

I don’t know about the differences. I only bind things when I am passing a parameter to a function. In this case I am only calling a function and not passing it any parameters.