This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Use ES2016 Property Initializer Syntax in ES6 classes

2:26 React lesson by

Create react app provides support for es2016 property initializer syntax out of the box. In this lesson, we’ll refactor the App component to use property initializers and look at the advantages of this syntax.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

Create react app provides support for es2016 property initializer syntax out of the box. In this lesson, we’ll refactor the App component to use property initializers and look at the advantages of this syntax.

Avatar
Tomás Francisco

Awesome!! I didn't know about this syntax. This definitely will improve my code :D

In reply to egghead.io
Avatar
Hozefa

Whats the babel setting we need to use here. Is this in stage-2 ?

In reply to egghead.io
Avatar
Andrew Van Slaars

Hozefa,

This course uses create react app. In CRA's babel config, they use babel-preset-react-app which has a dependency on babel-plugin-transform-class-properties.

Hope this helps.

In reply to Hozefa
Avatar
jhonnatan

Is there any performance implication when using this syntax? Taking a look of the babel playground when you create a method of a class it gets transpiled and added to the prototype however, with class initializer the method is added to every instance yo create. How will this affect multiple component in React? you can check it in this link

Avatar
Andrew Van Slaars

jhonnatan,

You're right, it will create the function for each instance of the component when using this syntax. In this case, all of the methods are attached to the top-level App component, so there will typically only be a single instance. I suppose there is potential for performance implications, but it would depend greatly on the scale of your application and how many instances you are creating of class components.

In reply to jhonnatan

In this component, we're using the constructor() to define this application's initial state. We're also binding the custom methods that we've defined to this, ensuring that those methods have the correct context when reading state and calling setState for updates.

These binding statements are a bit redundant. They are also easy to forget about, so you try to run your app, and a call to setState doesn't work as expected. Luckily, create-react-app shifts with the proper configuration to allow us to use property initializer syntax.

To demonstrate, let's convert the code in this constructor() into property initializers. I'm going to start by grabbing the entire initial state object, and cutting that, and putting it above the constructor(). I'm going to remove the reference to this.

App.js

class App extends Component {
    state = {
        todos: [
            {id: 1, name: 'Learn JSX', isComplete: true},
            {id: 2, name: 'Build an Awesome App', isComplete: false},
            {id: 3, name: 'Ship It', isComplete: false}
        ],
        currentTodo: ''
    }

    constructor() {
        super()

        this.handleInputChange = this.handleInputChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.handleEmptySubmit = this.handleEmptySubmit.bind(this)
    }

    ...

With property initializer syntax, state is now an instance property of this class just like it was before, and it's still available as this.state in this component's methods. Let's take a look at these method bindings. Each one of these is simply binding this to the method so that we have access to this.setState and this.state within those methods.

If we initialize these methods as properties, then we don't need to add this extra binding. For this, all we have to do is update each of these. We're going to set handleSubmit as a property, to equal an arrow function that handles our event. I'm going to do the same thing with handleEmptySubmit.
Adding an = and a =>. The same again with handleInputChange.

handleSubmit = (evt) => {...}

handleEmptySubmit = (evt) => {...}

handleInputChange = (evt) => {...}

Now that we've made those updates, we can come back up to our constructor() and we can get rid of these extra bind statements. Now that we've done all that refactoring, we're left with a constructor() that simply calls super().

constructor() {
    super()
}

If I save this, and without the browser reload, we can come over here and I'm going to open up the dev tools. We'll see in the console that there's a warning that we have a useless constructor(). We can just go in here and we can take the constructor() out, because we're no longer doing anything unique to our component limit.

// REMOVED
constructor() {
    super()
}

We can save that again. When the browser reloads the useless constructor() warning goes away. We can verify that we didn't break anything with our refactoring. We'll try to submit an empty form. We'll get our warning.

If I give it a valid entry, I should be able to submit. It updates our todoList.

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