715

I've seen both used interchangeably.

What are the main use cases for both? Are there advantages / disadvantages? Is one a better practice?

8 Answers 8

990

The two approaches are not interchangeable. You should initialize state in the constructor when using ES6 classes, and define the getInitialState method when using React.createClass.

See the official React doc on the subject of ES6 classes.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { /* initial state */ };
  }
}

is equivalent to

var MyComponent = React.createClass({
  getInitialState() {
    return { /* initial state */ };
  },
});

Note that in the constructor, you should always assign to this.state directly, and that's the only place where this is allowed; You should use this.setState(...) everywhere else.

6
  • 11
    You do not need to add props as an argument to constructor unless you're using it. Similarly super() would be fine here
    – inostia
    Commented Aug 23, 2016 at 17:22
  • 10
    @inostia the React documentation recommends to always pass props to super() (facebook.github.io/react/docs/…). But I don't know the reason for that recommendation. You're right, passing props to super() is not actually necessary since this.props is still accessible in render() and other methods either way. Perhaps the recommendation is for compatibility with potential future features. Commented Jan 1, 2017 at 13:52
  • This is the most relevant section of the React doc: facebook.github.io/react/docs/… Commented Jan 20, 2017 at 8:58
  • @AlexandreKirszenberg If you were calling a function from your constructor would you still modify this.state in that function, or rather use setState() instead? (Supposing the function is only ever called from the constructor.) Commented Mar 24, 2017 at 0:07
  • 5
    @TaylorEdmiston You would need to modify this.state directly. I'd recommend making functions that take in (state, props) and return a new state, so that you can either do this.state = myFn(null, props) in the constructor or this.setState(myFn) anywhere else. Commented Mar 24, 2017 at 11:38
180

The difference between constructor and getInitialState is the difference between ES6 and ES5 itself.
getInitialState is used with React.createClass and
constructor is used with React.Component.

Hence the question boils down to advantages/disadvantages of using ES6 or ES5.

Let's look at the difference in code

ES5

var TodoApp = React.createClass({ 
  propTypes: {
    title: PropTypes.string.isRequired
  },
  getInitialState () { 
    return {
      items: []
    }; 
  }
});

ES6

class TodoApp extends React.Component {
  constructor () {
    super()
    this.state = {
      items: []
    }
  }
};

There is an interesting reddit thread regarding this.

React community is moving closer to ES6. Also it is considered as the best practice.

There are some differences between React.createClass and React.Component. For instance, how this is handled in these cases. Read more about such differences in this blogpost and facebook's content on autobinding

constructor can also be used to handle such situations. To bind methods to a component instance, it can be pre-bonded in the constructor. This is a good material to do such cool stuff.

Some more good material on best practices
Best Practices for Component State in React.js
Converting React project from ES5 to ES6

Update: April 9, 2019,:

With the new changes in Javascript class API, you don't need a constructor.

You could do

class TodoApp extends React.Component {

    this.state = {items: []}
};

This will still get transpiled to constructor format, but you won't have to worry about it. you can use this format that is more readable.

react hooks image With React Hooks

From React version 16.8, there's a new API Called hooks.

Now, you don't even need a class component to have a state. It can even be done in a functional component.

import React, { useState } from 'react';

function TodoApp () {
  const items = useState([]);

Note that the initial state is passed as an argument to useState; useState([])

Read more about react hooks from the official docs

4
  • The difference radicates on the ES version you are using
    – jasmo2
    Commented Jan 10, 2017 at 1:15
  • 2
    Isn't there also a 3rd way of constructing object, as a functional 'State Hook' ? reactjs.org/docs/hooks-state.html I am new to react-native, so I may be wrong.
    – djangofan
    Commented Apr 8, 2019 at 17:47
  • 2
    Hi @djangofan, I wanted to update this for some time now. Thank you for pushing me in that direction. I've added the new short hand with class fields and useState with React hooks. Commented Apr 9, 2019 at 14:29
  • Can you explain what is super() and why we pass props to them as an argument? @sudobangbang
    – DevAS
    Commented Jul 31, 2019 at 8:42
36

OK, the big difference is start from where they are coming from, so constructor is the constructor of your class in JavaScript, on the other side, getInitialState is part of the lifecycle of React.

constructor is where your class get initialised...

Constructor

The constructor method is a special method for creating and initializing an object created with a class. There can only be one special method with the name "constructor" in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method.

A constructor can use the super keyword to call the constructor of a parent class.

In the React v16 document, they didn't mentioned any preference, but you need to getInitialState if you using createReactClass()...

Setting the Initial State

In ES6 classes, you can define the initial state by assigning this.state in the constructor:

class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }
  // ...
}

With createReactClass(), you have to provide a separate getInitialState method that returns the initial state:

var Counter = createReactClass({
  getInitialState: function() {
    return {count: this.props.initialCount};
  },
  // ...
});

Visit here for more information.

Also created the image below to show few lifecycles of React Compoenents:

React lifecycle

2
  • 1
    I would suggest adding componentWillReceiveProps to the diagram, since the OP was about state in components.
    – Pete
    Commented Feb 20, 2019 at 7:30
  • 1
    Can you explain what is super() and why we pass props to them as an argument? @Alireza
    – DevAS
    Commented Jul 31, 2019 at 8:38
11

If you are writing React-Native class with ES6, following format will be followed. It includes life cycle methods of RN for the class making network calls.

import React, {Component} from 'react';
import {
     AppRegistry, StyleSheet, View, Text, Image
     ToastAndroid
} from 'react-native';
import * as Progress from 'react-native-progress';

export default class RNClass extends Component{
     constructor(props){
          super(props);

          this.state= {
               uri: this.props.uri,
               loading:false
          }
     }

     renderLoadingView(){
          return(
               <View style={{justifyContent:'center',alignItems:'center',flex:1}}>
                    <Progress.Circle size={30} indeterminate={true} />
                    <Text>
                        Loading Data...
                    </Text>
               </View>
          );
     }

     renderLoadedView(){
          return(
               <View>

               </View>
          );
     }

     fetchData(){
          fetch(this.state.uri)
               .then((response) => response.json())
               .then((result)=>{

               })
               .done();

               this.setState({
                         loading:true
               });
               this.renderLoadedView();
     }

     componentDidMount(){
          this.fetchData();
     }

     render(){
          if(!this.state.loading){
               return(
                    this.renderLoadingView()
               );
          }

          else{

               return(
                    this.renderLoadedView()
               );
          }
     }
}

var style = StyleSheet.create({

});
0
2

These days we don't have to call the constructor inside the component - we can directly call state={something:""}, otherwise previously first we have do declare constructor with super() to inherit every thing from React.Component class then inside constructor we initialize our state.

If using React.createClass then define initialize state with the getInitialState method.

0

The big difference is start from where they are coming from, so constructor is the constructor of your class in JavaScript, on the other side, getInitialState is part of the lifecycle of React . The constructor method is a special method for creating and initializing an object created with a class.

0

If someone is still looking for answer then this link will be helpful Link

The constructor and getInitialState both in React are used to initialise state, but they can't be used interchangeably.

We use getInitialState with React.createClass and constructor is used with React.Component.

The constructor is the ideal place to set up your component's initial state. Instead of using setState() in other methods, you will need to assign the initial state directly.

class Hello extends React.Component { 
   constructor(props) { 
   super(props); 
   this.setState({ 
  title: 'This is the first test' 
   }); 
}   
  render() { 
    return <div>{this.state.title} </div> 
  } 
}   
ReactDOM.render(<Hello />, document.getElementById('container'));

The main fundamental difference between ES5 and ES6 is in the new class keyword. ES5 didn't provide the convenience of defining the React component as classes however ES did provide the convenience to define react component as class.

and more simple is that getInitialState is the ES5 friendly method to define the initial state of a React component. We use getInitialState with React.createClass and constructor is used with React.Component

Example:

class Goodmorning extends React.Component { 
  render() { 
    return <span>Good Morning</span>; 
  } 
}
It would rely on helper module called create-react-class: 
var createGoodmorningReactClass = require('create-react-class'); 
var Goodmorning = createReactClass({ 
  render: function() { 
    return <span>Good Morning</span>; 
  } 
}); 
The object passed into create-react-class that is defined in initial stage by calling the getInitialState attribute: 
 var Goodmorning = createReactClass({ 
  getInitialState: function() { 
    return {name: this.props.name}; 
  }, 
  render: function() { 
    return <span>Good {this.state.name}</span>; 
  } 
}); 
In ES6 implementation: 
class Goodmorning extends React.Component { 
  constructor(props) { 
    super(props); 
    this.state = { 
      name: props.name 
    } 
  } 
  render() { 
    return <span>Good {this.state.name}</span>; 
  } 
} 

and also read this article if someone is still looking for an answer. Link

-1

In constructor we should always initialize the state.

1
  • 1
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Jan 2, 2022 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.