What is State?

Hrishi Mittal
State is a way for React components to maintain and track changes in application data and update the UI accordingly.

So far, in our example code, we’ve only looked at static data. But any non-trivial app typically has some dynamic data.

For example, even if you are building a simple to-do list app, you’ll need to store the list items, whether they are completed or not, the order of the items, the date of the items, etc.

All of this dynamic data is managed using state inside a React app.

Before React Hooks were introduced in React version 16.8, only class components could have state, functional components did not. This is why one pattern you often saw in React apps is converting functional components to class components when they needed to introduce state.

However, since React Hooks have been introduced, state is now available in function components via the useState Hook. You can learn about it in the React Hooks module.

A class component’s state can be accessed via this.state just like we access its props via this.props, and when a component’s state data changes, the rendered markup is automatically refreshed by invoking the render function.

So let’s look at how we would implement state in our previous example where we introduced the name prop.

Say, instead of displaying a static message of “Hello, World!”, we want to display “Hello” along with whatever the user types into an input text field.

Let’s first add a form and an input field to the render method of our component:

  render() {
    return (
      <div>
        <form>
          <input />
        </form>
        <h1>Hello {this.props.name}!</h1>
      </div>
    )
  }
Note that React requires all JSX code returned by the render method to be enclosed within a single element. So here we’re enclosing everything inside a single div tag.

Now we’ve added an input field. When the user types in the field that value should be displayed below with “Hello”.

So first let’s add a method called changeName to capture and use the value using the onChange event for the input field:

<input onChange={this.changeName} />

And let’s define changeName:

  changeName = (e) => {
    this.setState({
      name: e.target.value
    })
  }
Every time the field value changes, this function changeName is called, which calls this.setState, which is how you change state in React.

React provides the setState method as an efficient way of changing state values immutably instead of mutating them directly.

You would typically store a number of values inside state, but you only need to pass the ones you want to change to setState.

So we change the value of name to e.target.value, where e is the onChange event and the target is the input field.

And now we can use the value of name from the state instead of props to display next to “Hello”:

<h1>Hello {this.state.name}!</h1>

We don’t need to pass the name prop to Hello any more inside ReactDOM.render.

For this to work, we also need to initialise the state with a default value.

We can do that in the constructor method of the class:

  constructor(props) {
    super(props)
    this.state = {
      name: 'World'
    }
  }
Note that state is simply defined as a JavaScript object.

So that’s what the component is going to initialise to, and then, when the user types in the input field, every time that field value changes, the onChange event triggers a call to this.changeName, which calls this.setState and sets the value of name in the state to the value of the input field.

We can also set the value of the input field to this.state.name so that it uses the initial state value as well.

<input onChange={this.changeName} value={this.state.name} />

Here’s the full code and you can run it on this codepen:

class Hello extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      name: 'World'
    }
  }

  changeName = (e) => {
    this.setState({
      name: e.target.value
    })
  }

  render() {
    return (
      <div>
        <form>
          <input 
            onChange={this.changeName}
            value={this.state.name} />
        </form>
        <h1>Hello, {this.state.name}!</h1>
      </div>
    )
  }
}

ReactDOM.render(<Hello />, document.getElementById('app'));
So this is a very simple example of how state works in React.

setState can also take a callback function as an additional argument, if you want something to happen after state has been updated.

We’ll see more complex uses of state as we build our Eventlite app in this course.