State

Props vs. State

Props
State

function parameters: props get passed to the component

variables in the function body: state is managed within the component

props are immutable

state can be changed

can be accessed using props and this.props

can be accessed using useState hook and this.state

Here is how we can set up state within a class component:

import React, { Component } from "react";

class Message extends Component {
  constructor(props) {
    super(props);
    // Creating state object
    this.state = {
      message: "Welcome visitor",
    };
  }

  changeMessage() {
    this.setState({
      message: "Thank you for subscribing",
    });
  }

  state = {};
  render() {
    return (
      <div>
        <h1>{this.state.message}</h1>
        <button onClick={() => this.changeMessage()}>Click me!</button>
      </div>
    );
  }
}

export default Message;

The above code renders a button that when clicked, changes the state message to a different one and updating the DOM in real time.

Using setState method

We can use the setState method to update the state as follows:

import React, { Component } from "react";

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0,
    };
  }

  increment() {
    this.setState({
      count: this.state.count + 1,
    });
    console.log(this.state.count) // log value to console
  }

  render() {
    return (
      <div>
        <h1>{this.state.count}</h1>
        <button onClick={() => this.increment()}>Increment</button>
      </div>
    );
  }
}

export default Counter;

Asynchronicity in setState and Callback functions

Note that calls to setState are asynchronous, so console.log(this.state.count) is called before the state is updated, so the value may differ. To handle asynchronous events and execute code only after the state is updated, you can pass in a second parameter as a callback function like follows:

increment() {
    this.setState({
      count: this.state.count + 1,
    }, () => {console.log(this.state.count)});
  }

Multiple setState calls

When you call the setState function multiple times, it may group the calls for better performance. So for example, a code like the one below may not update the value five times, but rather it would only update the state once.

incrementFive() {
   this.increment();
   this.increment();
   this.increment();
   this.increment();
   this.increment();   
}

To get around this limitation, if you want each setState call to reference the previous state, you would have to pass in the previous state as a parameter of the arrow function in setState as follows:

this.setState((prevState, props) => ({
      count: prevState.count + 1,
}));

After this change, the above incrementFive() function will work as intended, incrementing the state by 5 every time.

Destructuring State

We can destructure state to get cleaner, more elegant code as follows:

const { state1, state2 } = this.state

Last updated