⚠️ This lesson is retired and might contain outdated information.

Building a React.js App - ES6 Refactor: createClass to JavaScript Classes and propTypes

Tyler McGinnis
InstructorTyler McGinnis
Share this video with your friends

Social Share Links

Send Tweet
Published 9 years ago
Updated 6 years ago

In this video, we’ll walk through refactoring all of our note components to learn how to go from createClass to utilize JavaScript classes to build our React components as well as how to handle propTypes with ES6.

Let's go ahead and start refactoring some of our components. In this video, we are going to refactor all of the components in our notes folder, so let's go ahead and start with notes list.

The very first thing, instead of require, we need to import react from react. Once we've done that, now what we need to do is you'll notice here we're using react.createclass. Instead, let's go ahead and use the built-in ES6 class syntax.

We're going to go class, and the name of our class. We're going to have it extend react.component, and let's go ahead and capitalize Component. Now we've created our class, and real quick, let's go ahead and export defaults notes list.

What we're going to do now is have our render method. Remember, we don't need to type out function. Then I'm just going to copy this and throw it into here. The next thing we're going to do is let's go ahead and remove function and use our arrow syntax, as we talked about before.

Throughout this series, what we've done to loop over any lists is we've mapped outside of our return block here and then saved it into a variable, and then used our variable down here. I want to show you a little bit different syntax, just because you might see it.

I'm going to go ahead and take this map function and I'm going to throw it in right there, and then just fix this indention. This is technically the same thing as before, but instead of saving it to a variable, we're now actually just looping inside of our template.

Even take this a little bit further, so what I'm going to do is I'm going to destructure this .props. What that means is I can do something like this.

What that's done is it's taken the notes property on this .props, which is this guy right here, and saved it into a variable called notes. I can get rid of this line right here, so notes.map, and now what I can do -- and I could have done this before, but I'm just showing you now -- is I'm going to go ahead and use the implicit return here to keep this all on one line like that. Then we get something like this.

I'm not a huge fan of that, just because it seems a little bit scrunched just to force it to be on one line, but you've seen how powerful arrow syntax can be, and you've also seen this new idea of destructuring variables.

Let's see and make sure this still works. Notes list is still going fine, so cool. There is our notes list component.

The last change I'm going to make is, if you'll notice, this is how we had it before. If you use curly braces, then you need to have an explicit return here. But what some people do -- I'm just doing this so you can see all the different patterns -- is if you put a paren right here and not a curly brace, you can still...let's move this down here, and then we need two of these. Those match up, and then these should match up.

You can still take advantage of that implicit return, as long as you don't have a curly brace here. Some people really like this syntax. I'm not a huge fan of it, but it should still work, as well. Let's see.

There's our notes component still rendering. I'm going to keep it like this, but you've seen the different patterns that people use for looping over items in a react component.

Let's head over to our add note component, so same thing. Instead of that, we're going to import react from react. We're going to create a class called add note, which extends react component, export default, add note.

Let's go ahead and move our render method up, so here, we type render, which returns this UI. Add a handle submit method. Notice here, we don't have to put commas in between our methods because we're technically not in an object, so I'm going to move this up, as well.

One tricky thing that we need to do is when you're using react.createclass, that this keyword is automatically auto-bound to the correct context for you, which makes it really convenient. But one got-you you're going to have over and over again with ES6 classes in react is that this keyword is not auto-bound.

We want this keyword inside of this function to be the same as this keyword, so what we're going to do is just a handlesubmit.bind, so that this keyword inside of this context is the correct one. That looks good, so now the only thing left we need to do is worry about prop type.

What's a little bit different about prop types, too, is you have to add them to the class itself, so we're going to come up here and type "Add note," and as a property on add note, have our prop types object, and that should be it for this component.

One small fix real quick is to set this equal to the object instead of having a colon, so set this to equals. Now we just need to do a few more things.

First, let's go ahead and fix our setref function, and delete all this junk down here. Get rid of the function keywords. We have setref now.

What we could do is we could come in here and do .bind this again, because remember that this keyword is going to be different. But another pattern that I really like is instead of doing .bind, what we can do is we can create a arrow function right here and then call this .setref. Then we're going to get a ref, and then let's pass that there.

Remember, arrow functions don't create their own context. This keyword inside this arrow function is the exact same as the one out here, so this is actually the preferred way that I like to get around the auto-binding issue. Instead of using .bind, I just like to create these arrow functions. Then we'll invoke handle submit, and then this function will run.

This looks good. Let's go ahead and check webpack. Let's start webpack, and it looks like we have an issue. That's back in notes list, so come here.

You can't destructure like this. You obviously need to assign it a variable type, so we have const. That looks good.

What we need to do is every time we change a component, we need to go and figure out where that component is being required and change that, as well. Let's go ahead, and everywhere we're using add note, which is right here, so we're going to import add note from add note, and then we also change notes list.

Let's go ahead and do that one, as well, and then let's check these files. I think we're good. Let's see if webpack's good. Let's see if we have any errors. So far, so good.

Let's go ahead and modify the last file, our notes JS file. I swapped out our require for some imports. Now let's go ahead and create a class notes which extends react component, and then we're going to export default notes.

Let's go ahead and move our render method up, so that looks good. Now the only thing left to do is our prop types.

Again, the very last thing is now we need to figure out where we're importing notes, or where we're requiring it, and modify that. Let's go ahead and change in our profile JS component to our file, import notes from notes, from this. There we go.

Nils
Nils
~ 8 years ago

What is the benefit of using es6 class instead of React.createClass ?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

That is a question that the JavaScript community is kind of up in arms about right now. I personally use createClass still as I'm not a huge fan of classes in JS. However, a lot of really smart people use class. Here's a pretty good article describing the pros and cons. http://reactjsnews.com/composing-components/

egghead eggo
egghead eggo
~ 8 years ago

The lesson video has been updated!

Jori
Jori
~ 8 years ago

Hi. First off, great series! A question though: why do we have to bind propTypes seperately to a class?

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Good question. class definitions in ES6 only allow you to define methods and not properties. Hence why we can't put propTypes by our methods in our class and instead need to be added after.

Derek Hannah
Derek Hannah
~ 8 years ago

Id advise against teaching the es6 class syntax, its harmful to all of us. We need to prefer composition over classical inheritance. https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3#.3ab6fv5ob

Derek Hannah
Derek Hannah
~ 8 years ago

also Peter Hunt of the Facebook React team has told me personally that they do not use the es6 class syntax at Facebook

Derek Hannah
Derek Hannah
~ 8 years ago

other than that this whole course was dope thanks!

Joel Hooks
Joel Hooks
~ 8 years ago

Id advise against teaching the es6 class syntax, its harmful to all of us. We need to prefer composition over classical inheritance. https://medium.com/javascript-scene/the-two-pillars-of-javascript-ee6f3281e7f3#.3ab6fv5ob

It's really not, all due respect to Mr Elliott, the es6 class syntax is the least of our problems.

Tyler McGinnis
Tyler McGinnisinstructor
~ 8 years ago

Just in case any beginners read this and get stressed out, I'd like to say I think it's more than fine to use ES6 classes for React. Dan is smarter than I am though and here's his opinion. https://medium.com/@dan_abramov/how-to-use-classes-and-sleep-at-night-9af8de78ccb4#.m2ph4tq8i

Kirk Sefchik
Kirk Sefchik
~ 8 years ago

The moment I start to refactor NotesList, I start getting the following error: ``` Warrning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of Notes.


Anyone have any idea why this is happening? It triggers as soon as I convert NotesList from `React.createClass` syntax to ES6 class syntax.
Peter
Peter
~ 7 years ago

I have exactly the same problem, any one knows what the reason is for that? Checked all the code and is exactly the same way as in the video.

Robert Misior
Robert Misior
~ 7 years ago

You need to change the Notes to use import syntax for the NotesList:

import NotesList from './NotesList';

Markdown supported.
Become a member to join the discussionEnroll Today