654

When is it important to pass props to super(), and why?

class MyComponent extends React.Component {
  constructor(props) {
    super(); // or super(props) ?
  }
}
Misha Moroshko
  • 166,356
  • 226
  • 505
  • 746

10 Answers10

835

There is only one reason when one needs to pass props to super():

When you want to access this.props in constructor.

Passing:

class MyComponent extends React.Component {    
    constructor(props) {
        super(props)

        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

Not passing:

class MyComponent extends React.Component {    
    constructor(props) {
        super()

        console.log(this.props)
        // -> undefined

        // Props parameter is still available
        console.log(props)
        // -> { icon: 'home', … }
    }

    render() {
        // No difference outside constructor
        console.log(this.props)
        // -> { icon: 'home', … }
    }
}

Note that passing or not passing props to super has no effect on later uses of this.props outside constructor. That is render, shouldComponentUpdate, or event handlers always have access to it.

This is explicitly said in one Sophie Alpert's answer to a similar question.


The documentation—State and Lifecycle, Adding Local State to a Class, point 2—recommends:

Class components should always call the base constructor with props.

However, no reason is provided. We can speculate it is either because of subclassing or for future compatibility.

(Thanks @MattBrowne for the link)

Robin Pokorny
  • 10,657
  • 1
  • 24
  • 32
  • 20
    I think you are correct, despite the other answers getting more votes. `this.props` is `undefined` unless passed to `super()`. Either way, it does not affect later rendering or availability of `this.props` in the `render()` function. – Micros Jan 29 '16 at 11:11
  • I find the answer confusing, because if I pass `props` to super I get access to `this.props` not only in the `constructor() but in the entire class. I don't find it redundand at all. – Rotareti Jul 16 '16 at 19:13
  • 3
    @Rotareti, no, actually rest of the class does not depend on this construct, that is the point. Component receives props by a different way that by constructor parameter. And since you pass initial props to `super`, you have reference to them in the constructor. – Robin Pokorny Jul 17 '16 at 18:42
  • 1
    I have made a pen which shows this: http://codepen.io/netsi1964/pen/PGZApy/ – Netsi1964 Oct 12 '16 at 09:00
  • 8
    According to the React documentation, you should always pass `props` to `super()`: https://facebook.github.io/react/docs/state-and-lifecycle.html#adding-local-state-to-a-class. I'm not sure why, since as you point out `this.props` is accessible in other methods either way...perhaps they're recommending this for future compatibility in case future versions of React might want to do something with `props` in the constructor? – Matt Browne Jan 01 '17 at 13:45
  • 1
    @MattBrowne, good catch! I believe that is because you can subclass components and create a chain of inherited components. Then class higher would not know about those props. However, that is just a speculation. – Robin Pokorny Jan 02 '17 at 09:32
  • I think, "*When you want to access this.props in constructor,*" confused me a little, esp when followed by, "*Which is prob redundant since you already have a reference to it.*" There, "it" === the *content* within `props` elsewhere, not literally the `this.props` named reference. That is, ***as a side effect*** of including the named arg in your `super` call, you will *also* have `this.props` throughout the constructor, though the constructor's named argument makes that side effect redundant. Though, as @MattBrowne says, passing the arg to super is precisely what you *should* do. Sound right? – ruffin Apr 04 '17 at 18:39
  • @ruffin, I am not sure I understand what you found confusing. I decided to add code examples which I believe will help. Do you still find it confusing? At the bottom of the answer, I discuss what the docs recommend. Should that part be also updated? – Robin Pokorny Apr 06 '17 at 08:03
  • 1
    Your code examples precisely address what confused me the first time. If I could upvote again, I would. ;^) Thanks! – ruffin Apr 06 '17 at 16:57
  • 29
    Maybe I'm just opening a can of worms here, but **why _ever_ pass `props` to `super` when, as you pointed out, the `props` parameter is right there available for us to use within the constructor**, and `this.props` works everywhere else? Is there a benefit at all to using `this.props` over just `props`? Is it bad practice to destructure off of `props` in the constructor? I think I'm still failing to see a case when you'd ever need to pass `props` to `super`, but I'm willing to bet it's just my ignorance, ha. – indiesquidge Aug 22 '17 at 04:30
  • @indiesquidge, there is no known reason why to do that. It is just recommended in the docs and it might help you in the future, or not. I'd say it's safe to omit it now. – Robin Pokorny Aug 22 '17 at 13:00
  • @indiesquidge - I'm also failing to see strong reasoning in using `super()` vs `super(props)` in a React component based on the current discussion of this thread. However, my thought is that `this.props` is the standard use case when a component is mounted, and therefore using `props` is inconsistent and may lead to subtle bugs. For example, someone could write a script that parses `this.props` instead of `props` from a constructor's source code, and not really think twice that `props` is allowed as well. – tim-montague Sep 04 '17 at 10:37
  • 16
    If you use `super(props)`, you can call methods that use `this.props` *in from constructor*, like `this.doStuffUsingThisDotProps()`, without having to pass on the props parameter to those methods/functions. I just wrote a constructor doing this, which seemingly would require me to use `super(props)` first, according to the answers to this question. – Victor Zamanian Jan 09 '18 at 09:03
  • 1
    This might be compatibility issue or "future thinking" of react. At strongly typed languages such as C# or Java, you will have to pass constructor parameters to base class if it is enforced by abstract/base class. So, if react developers are seeking JavaScript becoming with more strongly typed with ES6 standards and TypeScript, it might be told it is a good practice to pass it through. – Teoman shipahi May 26 '18 at 21:00
  • They suggest to call base constructor with props on their documentation, but I found a thread which not strongly suggesting about that: https://discuss.reactjs.org/t/should-we-include-the-props-parameter-to-class-constructors-when-declaring-components-using-es6-classes/2781 – Bayu Nov 14 '18 at 06:37
  • @Bayu, thanks for the link. I mention this thread in the answer already ;) – Robin Pokorny Nov 14 '18 at 08:24
  • 1
    @RobinPokorny, oh... yeah, you are right :). I got those link from another googling activity, but was not click on yours ( because I didn't know if Sophie Alpert is official React team ) LOL. It strange the person in React team speak differently with their documentation. – Bayu Nov 14 '18 at 09:21
  • The other link says that : "According to Ben Alpert with the React team it's only necessary to pass props into the constructor if you intend on using this.props inside the constructor. After the constructor is invoked, React attaches the props to the component from the outside." https://stackoverflow.com/questions/35835371/is-the-call-to-superprops-in-an-es6-class-important – peevesy Jan 30 '20 at 05:19
  • @peevesy, what do you mean? That is exactly what I link in the answer. – Robin Pokorny Feb 02 '20 at 12:30
73

In this example, you are extending the React.Component class, and per the ES2015 spec, a child class constructor cannot make use of this until super() has been called; also, ES2015 class constructors have to call super() if they are subclasses.

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

By contrast:

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

More detail as per this excellent stack overflow answer

You may see examples of components created by extending the React.Component class that do not call super() but you'll notice these don't have a constructor, hence why it is not necessary.

class MyOtherComponent extends React.Component {
  render() {
    return <div>Hi {this.props.name}</div>;
  }
}

One point of confusion I've seen from some developers I've spoken to is that the components that have no constructor and therefore do not call super() anywhere, still have this.props available in the render() method. Remember that this rule and this need to create a this binding for the constructor only applies to the constructor.

Ankur Soni
  • 5,725
  • 5
  • 50
  • 81
Dave
  • 849
  • 7
  • 6
  • 18
    Thanks a lot for your answer, but it doesn't answer my original question (difference between `super()` and `super(props)`). – Misha Moroshko Dec 06 '15 at 07:18
65

When you pass props to super, the props get assigned to this. Take a look at the following scenario:

constructor(props) {
    super();
    console.log(this.props) //undefined
}

How ever when you do :

constructor(props) {
    super(props);
    console.log(this.props) //props will get logged.
}
Nahush Farkande
  • 5,290
  • 3
  • 25
  • 35
  • 1
    The best answer in the list. – Basavaraj Hadimani Dec 18 '18 at 05:45
  • 2
    This answer is half correct, This example is only for the constructor method. For example, even if you don't write super(props), this.props under the render method will still be assigned and available. The only reason mentioned above is when using this.props in the constructor. – Ofir Hadad Feb 24 '20 at 18:48
23

When implementing the constructor() function inside a React component, super() is a requirement. Keep in mind that your MyComponent component is extending or borrowing functionality from the React.Component base class.

This base class has a constructor() function of its own that has some code inside of it, to setup our React component for us.

When we define a constructor() function inside our MyComponent class, we are essentially, overriding or replacing the constructor() function that is inside the React.Component class, but we still need to ensure that all the setup code inside of this constructor() function still gets called.

So to ensure that the React.Component’s constructor() function gets called, we call super(props). super(props) is a reference to the parents constructor() function, that’s all it is.

We have to add super(props) every single time we define a constructor() function inside a class-based component.

If we don’t we will see an error saying that we have to call super(props).

The entire reason for defining this constructor() funciton is to initialize our state object.

So in order to initialize our state object, underneath the super call I am going to write:

class App extends React.Component {
  constructor(props) {
      super(props);

      this.state = {};
   }

  // React says we have to define render()
  render() {
    return <div>Hello world</div>;
  }
};

So we have defined our constructor() method, initialized our state object by creating a JavaScript object, assigning a property or key/value pair to it, assigning the result of that to this.state. Now of course this is just an example here so I have not really assigned a key/value pair to the state object, its just an empty object.

Daniel
  • 14,004
  • 16
  • 96
  • 156
21

Dan Abramov wrote an article on this topic:

Why Do We Write super(props)?

And the gist of it is that it's helpful to have a habit of passing it to avoid this scenario, that honestly, I don't see it unlikely to happen:

// Inside React
class Component {
  constructor(props) {
    this.props = props;
    // ...
  }
}

// Inside your code
class Button extends React.Component {
  constructor(props) {
    super(); //  We forgot to pass props
    console.log(props);      // ✅ {}
    console.log(this.props); //  undefined 
  }
  // ...
}
Edgar
  • 6,022
  • 8
  • 33
  • 66
Alfonso Embid-Desmet
  • 3,561
  • 3
  • 32
  • 45
17

As per source code

function ReactComponent(props, context) {
  this.props = props;
  this.context = context;
}

you must pass props every time you have props and you don't put them into this.props manually.

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 1
    I'm still not clear on this. if you look at [these](https://github.com/rackt/redux/blob/master/examples/real-world/components/Explore.js) two [components](https://github.com/rackt/redux/blob/master/examples/real-world/components/List.js), you can see one calls `super(props)` and the other doesn't. But their consumers both set props. What is the difference? – Kyeotic Oct 23 '15 at 18:41
  • 1
    Does this mean that `this.props = props` and `super(props)` are the same thing? – reectrix Dec 15 '15 at 20:25
  • 1
    This is not true. [ReactElement](https://github.com/facebook/react/blob/3b96650e39ddda5ba49245713ef16dbc52d25e9e/src/isomorphic/classic/element/ReactElement.js#L52) actually sets `this.props` from the ‘outside’–irrespective of what is done in the constructor. – Robin Pokorny Jan 25 '16 at 14:58
13

super() is used to call the parent constructor.

super(props) would pass props to the parent constructor.

From your example, super(props) would call the React.Component constructor passing in props as the argument.

More information on super: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super

kspence
  • 422
  • 4
  • 9
  • 26
    Yes, that's what it does. But *why*? And *when* is one of the two forms required in React? – Bergi Sep 28 '15 at 12:27
6

For react version 16.6.3, we use super(props) to initialize state element name : this.props.name

constructor(props){
    super(props);        
}
state = {
  name:this.props.name 
    //otherwise not defined
};
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
shubham kapoor
  • 589
  • 6
  • 16
5

Here is the fiddle I've made:jsfiddle.net. It shows that props are assigned not in the constructor by default. As I understand they are assinged in the method React.createElement. Hence super(props) should be called only when the superclass's constructor manually assings props to this.props. If you just extend the React.Component calling super(props) will do nothing with props. Maybe It will be changed in the next versions of React.

Edgar
  • 6,022
  • 8
  • 33
  • 66
beshanoe
  • 222
  • 2
  • 8
5

Here we won't get this in the constructor so it will return undefined, but we will be able to fetch this outside the constructor function

class MyComponent extends React.Component {
  constructor() {
    console.log(this); // Reference Error i.e return undefined
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

If we are using super(), then we can fetch the "this" variable inside the constructor as well

class MyComponent extends React.Component {
  constructor() {
    super();
    console.log(this); // this logged to console
  }

  render() {
    return <div>Hello {this.props.name}</div>;
  }
}

So when we are using super(); we will be able to fetch this but this.props will be undefined in the constructor. But other than constructor, this.props will not return undefined.

If we use super(props), then we can use this.props value inside the constructor as well

Sophie Alpert's Answer

If you want to use this.props in the constructor, you need to pass props to super. Otherwise, it doesn’t matter because React sets .props on the instance from the outside immediately after calling the constructor.

VIKAS KOHLI
  • 8,164
  • 4
  • 50
  • 61