• 12 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 3/3/22

Understand Old React Syntax

When writing this course, React was on version 17.0.2 and has evolved over the years, which means that the way we write components today looks nothing like the way they were in the beginning. Unfortunately, that means some codebases contain components written using other syntaxes. Time to get back in our time machine to take a look over the main stages in React’s evolution. 🚀

Discover the Evolutionary Stages of React

In the Beginning: createClass

When React became open source in 2013, components were created with  React.createClass  . To give you an example, a  MyComponent  component that receives a  title  prop would be written as:

React.createClass({
   displayName: "MyComponent",
   render() {
      return (
         <div>
            <h1>{this.props.title}</h1>
         </div>
      )
   }
})

These days, though, this syntax is considered to be deprecated, and you won’t find it anywhere in React’s documentation.

However, you’re likely to stumble across class components.

Discover Class Components

With the addition of classes in ES 2015 (here is Mozilla’s documentation on classes), React wanted to align itself by creating class components. It was a time of major change. In this and the following chapters, we will go over their syntax, how to make API calls, and manage state and props in class components. 

Learn about the syntax of class components in the screencast below. 👇

If you’d like to see the full code for this whole component, you can find it here, on the GitHub repository.

Discover the Syntax of Class Components

As you’ll have seen from the screencast above, class components have different syntax. We’re going to create a new  EmailInput  component and put it in the footer.

Start by declaring the component:

import { Component } from 'react'

class EmailInput extends Component {
   constructor() {
   }
   render() {
      return (
         <div>
            <input />
         </div>
      )
   }
}

export default EmailInput

You declare your components with  class  and   extends Component. If you’ve ever worked with classes, you’ll have already seen  extends  and  constructor  . It’s important to know that  constructor  (documentation here) is a method for creating and initializing an object when you’re using the keyword class.

What’s is  render  ?!

It's one of your component’s methods. In fact, it’s the only method that you are obliged to call in your component (so it needs to be there). For certain events, your component will have to re-render. Each time, this method will recalculate what is declared and display what is returned.

A new render will happen every time an update takes place:

  • When initializing the  constructor .

  • Whenever a prop is updated. 

  • For every change to state (more on this later).

render  is not a feature of function components.

Note that  render  must return JSX (which will be in the  return  ). But if you have nothing to return in your  render  , you can also return  null  .

Access Props

We’re now going to add a bit of style to the component that we’ve just created, creating a version for the  darkMode  and one for the  lightMode  . In a previous chapter, you learned that using context is much easier with hooks. Unfortunately, you can’t use hooks from class components. Therefore, you have to pass the  theme  as props.

But we don’t have any parameters in which we can get props, so how do we get them?

Don't worry, there’s a way to get your props in class components by using  this.props  throughout your component – whether it’s in the  return  ,render  , or a method. Start by initializing them in the  constructor  , and then pass the initial  state  , even if you don’t need it for now (it keeps our linter happy).

Declare the following in your component:

class EmailInput extends Component {
   constructor(props) {
      super(props)
      this.state = {
         inputValue: '',
      }
   }

   render() {
   // Here we get theme by destructuring this.props
      const { theme } = this.props
      return (
         <div>
            <input />
         </div>
      )
   }
}

With this, you can apply a different style depending on your   theme   . You can find this style on P4C1-exercise.

Then what’s  this ?

If you’re familiar with JavaScript, you’ll have come across  this , which refers to the object it belongs to. If you need a reminder, you can see how to define a class in JavaScript in the chapter “Define objects and their attributes with classes” of the course Learn Programming With JavaScript.

Here,  this  refers to the component: it is the  props  and the  state  of  EmailInput  .

Careful, though – when you declare the methods (which are kind of functions) in your components, you need to pay attention to the  bind  .

The what? The "bind"?

To put it simply, you use bind to bind your methods to your class component: they need to be correctly bound to the  this  . You’ll understand better once you see the  state  . ✨

Manage State With  setState

Let’s now manage the value entered into the   EmailInput  with  setState  .

Isn’t  setState  more or less the same as  useState  ?

Not really. First of all,  useState  is a hook: it’s how you manage state for function components.  setState  is for class components. Although both functions deal with state, they do not work in the same way:

  •  useState  lets you declare your state variable, initialize its value, and get a function to update it. 

  • setState  only lets you update the state in your component. Remember, the initial state is declared in the  constructor  .

You have to go step by step to manage the state of the value entered into EmailInput . If you’re struggling to follow, all of the code you need is on the GitHub repository.

In the section just above, you initialized your state in the  constructor  with:

this.state = {
   inputValue: '',
}

You’re now able to declare a function to update the value of your state:

updateInputValue = (value) => {
   this.setState({ inputValue: value })
}

There is no need to have   const =    in front of your function. Usually, you’d have to initialize it, but given that you’re in a   class  ,  updateInputValue  is a method of your   EmailInput class.

Could we have put  updateInputValue  in the  render  ?

Yes, but everything within the  render  is run every time a prop or the state is updated. That means that your function would be declared again, which wouldn’t be very efficient, would it?

This method is called in  onChange  from  input  :

<input
   onChange={(e) => this.updateInputValue(e.target.value)}
/>

Here, every time a  setState  is run, it will trigger a new  render  in your component.

There are certain rules to follow for  setState  (the fact that  setState  is asynchronous, that state updates are merged, etc.). Learn these rules in React's documentation.

And just like you access  props  with  this.props  , you use  this.state  to access the current state. 

Do the following to display the input:

render() {
   return (
      <div>
         {this.state.inputValue}
         <input
            onChange={(e) => this.updateInputValue(e.target.value)}
         />
      </div>
   )
}

Back to this

Usually, when you declare a new function, you use the syntax  function myFunction()  . So why are we using an arrow function here?

To access your method in your class, you need to bind your function to your class. Arrow functions let you do this implicitly. Problem solved.

Without an arrow function, you’d have to do it explicitly like this: 👇

constructor(props) {
   super(props)
   this.updateInputValue = this.updateInputValue.bind(this)
   this.state = {
      inputValue: '',
   }
}

updateInputValue (value) {
   this.setState({ inputValue: value })
}

this  can be a bit tricky to grasp. That’s one of the reasons why React chose to promote function components, to make things easier at the learning stage. The Medium article “What is ‘this’ in React?” goes back over the key ideas. 

Give It a Go!

It’s time to put everything you’ve just learned into practice. To do this, I’ve turned the  Card  component into a class component and created an  EmptyList  component that lets you signal to the user that the skills list is empty (if they have answered ‘no’ to all questions). Your task is to:

  • Recreate the favorites system, which adds "⭐️" around the name of the freelancer that we’ve clicked on in  Card  , sticking with a class component. 

  • Transform the  EmailInput  component into a function component. 

  • Transform the  EmptyList  component into a function component. 

As usual, you’ll find the start of the exercise on the branch P4C1-begin, and the solution on P4C1-solution. Over to you! 🚀

Let’s Recap!

  • Class components appeared at the same time as  class  in JavaScript. 

  • A class component is declared withclass ComponentName extends Component    .

  • render  is called every time an update occurs. 

  • State is updated with  setState  , to which you pass an object as a parameter.

  • Props and state are accessed with  this.props   and  this.state  .

In the next chapter, we’ll look into another essential aspect of class components: lifecycle methods. You’ll also learn how to call an API in a class component. See you there! 🚀

Example of certificate of achievement
Example of certificate of achievement