Initializing state using class field declaration


5 years ago -  
React

If you want to initialize state in a class based component we have two options:

  • In constructor
  • As a class property

For class based components I used to initialize state in the constructor:

import React, { Component } from "react";

export class SampleComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [
        { id: this.getRandomInt(5), name: "Item 1" },
        { id: this.getRandomInt(5), name: "Item 2" },
      ],
    };
  }

  getRandomInt = (max) => {
    return Math.floor(Math.random() * Math.floor(max));
  };

  render() {
    return (
      <ul>
                        
        {this.state.items.map((item) => (
          <li key={item.id}>
            {item.name} - {item.id}
          </li>
        ))}
                    
      </ul>
    );
  }
}

This approach is fine, but you will have to make sure you call super(props). Sometimes we might forget to call super(props) in the constructor; in this case, the parent’s constructor won’t be executed, which will cause the following error:

ReferenceError: Must call the super(props) constructor in derived class before accessing ‘this’ or returning from derived constructor

It’s where using class field declaration comes in handy. It saves us a few keystrokes, so you don’t need to worry about calling super(props) anymore. So the previous example can be written as:

import React, { Component } from "react";

export class SampleComponent extends Component {
  getRandomInt = (max) => {
    return Math.floor(Math.random() * Math.floor(max));
  };

  state = {
    items: [
      { id: this.getRandomInt(5), name: "Item 1" },
      { id: this.getRandomInt(5), name: "Item 2" },
    ],
  };

  render() {
    return (
      <ul>
                        
        {this.state.items.map((item) => (
          <li key={item.id}>
            {item.name} - {item.id}
          </li>
        ))}
                    
      </ul>
    );
  }
}

The key point to remember here is that if you are going to call a method inside the state (getRandomInt in our case), you must declare your methods before declaring the state otherwise you will get the following error:

TypeError: this.getRandomInt is not a function

If you are using TypeScript then it has got your back and immediately yelling at you: