React State

I. What is State?

State is the data that a component maintains. Different from props, state can change its value.

state is stored in a JavaScript object.

To introduce state to a component, that component must be a class-based component.

II. Set up React State

1. Constructor(props)

Firstly, we need to add a constructor() method.

constructor() is a specific Javascript method that sets up the initial state of the component.

Class components should always call the base constructor with props.

Inside the constructor, we must call super() and pass in the props.

import React, {Component} from "react"

class App extends Component {
    constructor(props) {
        super(props)
    }
    
    render() {
        return (
            // Code here
        )    
    }
}

export default App

2. Adding an initial state to Class Components

After calling the super(props), we can set up our inital state.

To add state to a component, we use this.state. this.state is an object.

import React, {Component} from "react"

class App extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: "Jane",
            age: 18
        }
    }
    
    render() {
        return (
            <div>
                <h1>{this.state.name}</h1>
                <h3>{this.state.age} years old</h3>
            </div>
        )    
    }
}

export default App

To read a component’s state, use the expression this.state.name-of-property. The above component class reads a property in its state from inside of its render function.

III. Changing the state

For example, the following App is expected to increase the count by 1 point from 0.

  • We have an H1 displaying our state, which is count property. We initialize it from 0.
  • We add an event handler onClick to the button that runs the method handleClick.
import React from "react"

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            count: 0
        }
    }

    handleClick() {

    }
    
    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.handleClick}}>Change!</button>
            </div>
        )
    }
}

export default App

1. this.setState()

To change the state of a component, we use the method this.setState() that comes from the parent Class React.Component.

setState() will provide a new version of state and take an object literal.

Example

handleClick() {
    this.setState({ count: 1 })
}

If we’re changing the state based on the old state, we need to give setState a function, not an object.

This function takes prevState as a parameter and return an object that is the new state.

handleClick() {
    this.setState(prevState => {
        return {
            count: prevState.count + 1
        }
    })
}

2. Binding

Everytime we create a class method using setState, we need to bind this method to our own Class inside the constructor().

constructor(props) {
    super(props)
    this.state = {
        count: 0
    }
    this.handleClick = this.handleClick.bind(this)
}

Our final App.js file will become

import React from "react"

class App extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            count: 0
        }
        this.handleClick = this.handleClick.bind(this)
    }
    
    handleClick() {
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        })
    }
    
    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.handleClick}>Change!</button>
            </div>
        )
    }
}

export default App

3. State is not mutable

State is read only so you should not try to manually change the values of the state attributes.

If the state needs to be updated, the setState() method is the only way to change the state.

For example, don’t do this:

//incorrect, state should not be mutated directly
this.state.count = 1