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! šŸš€

Et si vous obteniez un diplƓme OpenClassrooms ?
  • Formations jusqu’à 100 % financĆ©es
  • Date de dĆ©but flexible
  • Projets professionnalisants
  • Mentorat individuel
Trouvez la formation et le financement faits pour vous