Can this.setState change multiple properties at once?

Question

In the context of this exercise, can this.setState change multiple properties at once?

Answer

Yes, you can use this.setState to change single, multiple, or even all properties of state at a time. When setting state for multiple properties, only the properties passed in will be updated.

For example, the following shows how the properties key1 and key3 of a state could be updated.

/* Given this state */
this.state = {
  key1: value1,
  key2: value2,
  key3: value3
}

/* We could use code like the following to update specific properties */
this.setState({ key1: newValue1, key3: newValue3 });
10 Likes

Here’s my version with the addition of button text change:

import React from 'react';
import ReactDOM from 'react-dom';

const green = '#39D1B4';
const yellow = '#FFD712';


class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      color: green,
      text: 'Change to yellow'
      };
    this.changeColor = this.changeColor.bind(this);
  }
  changeColor() {
    const newColor = this.state.color === green ? yellow : green;
    const newText = this.state.text === 'Change to green' ? 'Change to yellow' : 'Change to green';
    this.setState({
      color: newColor,
      text: newText
    });
  }
  render() {
    return (
      <div style={{background: this.state.color}}>
        <h1>
          Change my color
        </h1>
        <button onClick={this.changeColor}>
          {this.state.text}
        </button>
      </div>
    );
  }
}

ReactDOM.render(<Toggle />, document.getElementById('app'));
16 Likes

really confused by this lecture, is there any examples to show me how call this.state function work?

1 Like

Can I have the same event handler in one element?

import React from 'react';

import ReactDOM from 'react-dom';

const green = '#39D1B4';

const yellow = '#FFD712';

class Toggle extends React.Component {

  constructor(props){

    super(props);

    this.state = ({ color:green, text:'green' })

    this.changeColor = this.changeColor.bind(this);

    this.changeText = this.changeText.bind(this);

  }

changeColor(){

  const newColor = this.state.color == green ? yellow : green;

  this.setState({color: newColor});

}

changeText(){

  const newText = this.state.text == 'green' ? 'yellow' : 'green';

  this.setState({text: newText});

}

  render() {

    return (

      <div style={{background: this.state.color}}>

        <h1>

          The color is {this.state.text}

        </h1>

        <button onClick={this.changeColor} onClick={this.changeText} >Change color</button>

      </div>

    );

  }

}

ReactDOM.render(

  <Toggle/>, document.getElementById('app')

)
type or paste code here
````Preformatted text`
1 Like

Under the hood React uses AddEventListener, which allows you to attach multiple event listeners listening to event of the same type, but you’re right - it’s not the best practice! :smiley:
Instead for two independent operations I would create another method type property (i.e. clickHandler) that is executed onClick. Inside you could call the other two methods that change the state.

However in this case I would just replace the two handlers with a single handler:

import React from 'react';

import ReactDOM from 'react-dom';

const green = '#39D1B4';

const yellow = '#FFD712';

class Toggle extends React.Component {

  constructor(props){

    super(props);

    this.state = ({ color:green, text:'green' })
 
    this.handleClick = this.handleClick.bind(this);

  }

handleClick() {

    const newColor = this.state.color == green ? yellow : green;
    const newText = this.state.text == 'green' ? 'yellow' : 'green';

    this.setState({ cooler: newColor, text: newText });
}

  render() {

    return (

      <div style={{background: this.state.color}}>

        <h1>

          The color is {this.state.text}

        </h1>

        <button onClick={this.handleClick} >Change color</button>

      </div>

    );

  }

}

ReactDOM.render(

  <Toggle/>, document.getElementById('app')

)
1 Like

nice let me test it, this is great but we have to find how to bind multiple event handler

import React from 'react';
import ReactDOM from 'react-dom'

const green = '#39D1B4';
const yellow = '#FFD712';

class Toggle extends React.Component {
  constructor(props){
    super(props);
    this.state={
      color:green,
      text:'Change to yellow'
      }
    this.changeColor = this.changeColor.bind(this);


  }
  changeColor(){
    const Change=this.state.color==green? yellow :green;
    const changetxt=this.state.text=='Change to green'? 'Change to yellow' : 'Change to green'
     this.setState({ color: Change, text:changetxt });
  }
  render() {
    return (
      <div style={{background: this.state.color}}>
        <h1>
         <button onClick={this.changeColor}>
  {this.state.text}

</button>  <br />
{this.state.text} by clicking the button
        </h1>
      </div>
    );
  }
}


ReactDOM.render(
  <Toggle />,
  document.getElementById('app')
)Preformatted text