When do I need to pass 'props' to constructor()?

Hello.

Every lesson on the Code Camp React course includes ‘props’ in the constructor:

class Main extends React.Component {
constructor(props){
//etc, etc...
}
// etc, etc...
}

Can anyone tell me why?

1 Like

All the attributes of a react component in JSX are called “props”. So when you have a component like:

<Foo bar={blah()} xyzzy=123>

It will receive an object as the props parameter, with bar and xyzzy keys. In other words, it’s automatically passed for you. Very often, especially in functional components, you’ll see the props parameter in destructured form, e.g:

const Foo = ({bar, xyzzy}) => ...

Which if you’ve taken the ES6 curriculum on FCC, you know translates to:

const Foo = (props) => { let bar = props.bar; let xyzzy = props.xyzzy; ...

I think I understand what props are.

Let me put it another way - are there any circumstances when you wouldn’t have ‘props’ included in the constructor?:

constructor() {
  // code
}

or, whenever you write a constructor it has, by default, to have ‘props’?

constructor(props) {
  // code
}

(I’ve noticed that I can remove ‘props’ from super() from all of the Code Camp challenges (so far) - I googled this and found the following answer: “There is only one reason when one needs to pass props to super(): When you want to access this.props in constructor.”.)

1 Like

A component that takes no props at all isn’t very useful. There are plenty that declare no props at all and only act as containers, but even then they implicitly take a prop named children for that purpose. I suppose you could write a component that relied on global variables and took no props, but that’s tremendously bad practice in general, and especially so in React.

This is the reason. YMMV, but you don’t need a constructor most of the time. (Particularly if you’re using create-react-app or you’ve enabled class properties in a build step, most of the time can just look like:

class MyThing extends Component {
  state = {};

  componentDidMount() {
    dostuff()
  }

 componentWillUnmount() {
    undostuff()
  }

  render() {
    renderstuff()
  }
}

)

OK Thanks very much :slight_smile:

Dan Abramov wrote about this on his blog recently. You only need to read as far as is useful to you, but basically, you’re correct. Without passing props to super(), you can’t access this, and for good reason.

1 Like

As Abramov does mention in the blog post, calling super() in your constructor isn’t just advice for OO React components, it’s necessary for the correct behavior of any OO class that extends another (and not just in JS either!) It’s super interesting how it affects this, though, I never knew that before now.

1 Like

But this works:

class Main extends React.Component {
  constructor(){
    super()
    this.state = {
      name: "John"
    }
  }
  render() {
    return (
      <div>
        <h1>{this.state.name}</h1>
        {/* Output: John */}
      </div>
    );
  }
}

and so does this:

class Main extends React.Component {
  constructor(){
    super()
    this.state = {
      name: "John"
    }
  }
  render() {
    return (
      <div>
        <Child theName={this.state.name}/>
        {/* Output: John */}
      </div>
    );
  }
}

function Child(props){
  return(
    <h1>{props.theName}</h1>
  )
}

So this doesn’t seem to be affected by not having props in super() - nor in constructor(). I remain confused!

Yeah. I’m not one to hero-worship, but like his tagline says, he really does explain stuff with words and code.

I’m sorry: I wasn’t ultra-precise in an area where precision matters. If you read the article, you can see that I accidentally lumped together two (independently correct) statements:

  1. You can’t access this.props inside a constructor without calling super(props)
    1. passing props to super is critical here (if you read the article and click through the links he provides, you can see why exactly this is true.
  2. You can’t access this inside a constructor BEFORE calling super
    1. with or without having passed props to super(). The JS interpreter will throw an error to avoid issues wherein you might try to access properties/methods on this without them having been initialized.

super() is calling the constructor of the superclass (in this case, React.Component) with no args, whereas super(props) is passing the props to the constructor. If you don’t pass props in super(), you’ll still get a working this, yes, but I’m fairly sure this.props will be undefined, as well as a bunch of other stuff you need.

1 Like

From your original post:

Not this, or this.props outside of the constructor, just this.props inside the constructor.

1 Like

Right OK I think I get you - thanks for getting back on this ( and this) :slight_smile:

1 Like