What is the difference between using constructor vs state = {} to declare state in react component?

I found there is two way to declare state in class component like below

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'John'
        }
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

and

class App extends Component {
    state = {
       name: 'John'
    }

    render() {
        return  <div>{this.state.name}</div>
    }

}

What is the difference between these two?


They are roughly equivalent. The significant difference is that the initializer in the second example is executed before constructor.

The second approach uses class fields proposal.

It is not a part of ECMAScript standard yet so you need to set up transpiler properly to use the second approach.

UPD Take a look at Babel output to better understand how public instance fields work.


Use the constructor when you want to save props data into state

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      name: 'John'
    }
  }
}

Otherwise you can directly set the state for hard coded data

class App extends Component {
  state = {
    name: 'John'
  }
}

When you add a method to a class, its actually being added to the function’s prototype. like so:

class Same{
  thing() {}
}

// Equivalent to:

function Same() {}
Same.prototype.thing = function () {}

thing is defined once and shared across all instances of the class.

If you refactor it to use Class Fields as follow:

class Animal {
  thing() {}
  anotherThing = () => {} // Class Field
}

// Equivalent to:

function Animal () {
  this.anotherThing = function () {}
}

Animal.prototype.thing = function () {}

anotherThing is defined on each of newly created instance rather on the prototype.

Development Experience vs Performance

Its a trade-off you should consider. Class Fields makes your code looks readable and clean. However, Class Fields keeps a copy of anotherThing in each one of your instances.

Therefore, you should carefully think if you want to use them.