Enter Your Email Address to Watch This Lesson

Your link to unlock this lesson will be sent to this email address.

Unlock this lesson and all 829 of the free egghead.io lessons, plus get React content delivered directly to your inbox!



Existing egghead members will not see this. Sign in.

Just one more step!

Check your inbox for an email from us and click link to unlock your lesson.



Manage React Component State with setState

2:28 React lesson by

State is used for properties on a component that will change, versus static properties that are passed in. This lesson introduces you to updating state through a simple text input and displaying that in the browser.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

State is used for properties on a component that will change, versus static properties that are passed in. This lesson will introduce you to taking input within your React components.

Avatar
Richard

Can you explain why the need to use this.update.bind(this) in the onChange attribute?

Avatar
Joel

Can you explain why the need to use this.update.bind(this) in the onChange attribute?

Previously with React.createClass you would get autobinding. When you use es6 classes, this is no longer the case, so you need to explicitly bind the this scope of event handler functions. People will also do this in the constructor or through a more "es7" style property binding.

constructor(props) {
        super(props);
        this.update = this.update.bind(this);
    }
MyComponent extends React.Component {

    update = () => this. update();

    render() {
    // ...
In reply to Richard
Avatar
Irvin

Which is the preferred way?

In reply to Joel
Avatar
jeff

I would love a short tutorial about this.

In reply to Joel
Avatar
Somsubhra

I was trying to use ES7 style and was getting a syntax error..Is there anything I am doing incorrectly

class App extends React.Component {
...
update = () => this.updateEnteredText();
updateEnteredText(e){
...
}
render() {
.....

In reply to Joel
Avatar
Rajeev
_bind(...methods) {
  methods.forEach( (method) => this[method] = this[method].bind(this) );
 }

I am doing it this way and then inside constructor
this._bind('methodName1','methodName2');

In reply to Irvin
Avatar
Kode

Could I please ask which editor (Atom?) and what plugins you are using? It is like magic and I'd love to make those efficiency gains!

Avatar
Pete

I had some trouble with this because the code in the video does not match the code under Code. I was able to resolve it by adding:

import ReactDOM from 'react-dom';

and

changing:

export default App

to

ReactDOM.render(<App />, document.getElementById('app'));

The JSBin HTML file has script links to fb.me for react and react-dom, so that it does work there, but that is not part of the course lesson.

In further investigation, I found on the github repo for lesson 4 that main.js had been returned to its original state. In one of the earlier lessons, he deletes several lines, but never indicates in subsequent lessons that he put them back.

Avatar
Tommy

Thank you for this, this worked for me.

In reply to Pete

Unlike props, which are a collection of values that are meant to be passed into our component as static value, it's not meant to be changed by our component. State represents a collection of values that is meant to be managed, as well as updated by our component.

To get us started using state, I'm going to setup a constructor method here, and the first thing I'm going to do is, I'm going to call super(). This is going to give the keyword this the context within our component, rather than its parent class React.Component.

App.js

import React from 'react';

class App extends React.Component {
  constructor () {
    super();
    this.state = {

    }
  }
  render(){
    return (
      <h1>Hello World</h1>
    )
  }
}
export default App

Here, we're going to set up, this.state equal to an object, I'm going to create a key called txt, I'm going to say, This is the state text.

this.state = {
  txt: 'this is the state txt'
}

To use state within our JSX, we interpolate it just like we do this.props, but this time, we're going to say, this.state, and then, the key that we're looking for, in this case, it's txt. We can see in the browser there, we get this is the state text.

render(){
    return (
      <h1>{this.state.txt}</h1>
    )
  }

Again, this is meant to be managed and updated by our component. I'm going to create a method here called update, that takes in an event. It's important to note this is not a part of the specification, this is just a custom method on our component.

I'm simply going to call this.setState, we're going to pass in a new object, with a key of txt, and I'm going to get a new value off of that event, I'm going to say e.target.value.

App.js

update( e ){
  this.setState({txt: e.target.value})
}

Now to get that working, I'm going to wrap this JSX in a parent node, we only have a single node being delivered by our render method. I'm going to create an input here, and on its onChange event, I'm going to call this.update, the custom method that we created. I'm going to go ahead and bind that with a context of this.

render(){
    return (
      <div>
        <input type="text" 
          onChange={this.update.bind(this)}/>
        <h1>{this.state.txt}</h1>
      </div>
    )
  }

When we run that, we've got our default state text here, and when we type in this, this is the new text, we can see that our state is in fact being updated, and every time we call this.setState, our render method is being rerun. It's important to note here that, the call of this.setState only overwrites the values that we actually send into it.

If I created another value in our state for cat, and its default is 0. We'll go ahead and output that right here, after the text value. I'll just say cat.

class App extends React.Component {
  constructor () {
    super();
    this.state = {
      txt: 'this is the state txt',
      cat: 0
    }
  }
  update( e ){
  this.setState({txt: e.target.value})
}
  render(){
    return (
      <div>
        <input type="text" 
          onChange={this.update.bind(this)}/>
        <h1>{this.state.txt - {this.state.cat}}</h1>
      </div>
    )
  }
}

Save that. We can see that in the browser, when we change our state, the value for cat and our state is not lost, only the value for text is updated.

State Changed



HEY, QUICK QUESTION!
Joel's Head
Why are we asking?