2

I'm using ReactJS in Typescript. Do I need the "Constructor" code below? It works fine without it and I looked at the trans-piled JavaScript and it appears to add it in automatically anyway.

interface myProps {
   children?: any;
}
class MyButton extends React.Component<myProps, {}> {
    constructor(props: myProps) { //Needed ???
        super(props);
    }

    render() {
        return (<div>
            <button>
                {this.props.children}
            </button>
        </div>);
    } //end render.
} //end class.
Lambert
  • 2,233
  • 5
  • 29
  • 44

4 Answers4

5

No, you don't need to.

In fact, you could write a simple component like this as a function.

const MyButton = (props) => {
  return (
    <div><button>{props.children}</button></div>
  );
};
manonthemat
  • 6,101
  • 1
  • 24
  • 49
2

As mentioned in the accepted answer:

const MyButton = (props) => {
  return (
    <div><button>{props.children}</button></div>
  );
};

This works but it's not the same - not at all. This is constructing a StatelessComponent (without state, without lifecycle-hooks, it's just a plain function, returning only the JSX or the part of the "render" function).

If you need state or lifecycle-hooks, you must extend from React.Component - like it is already done in the question.

To actually answer your question - yes constructor is needed. That's because you are extending of an existing class which is already asking for an initial property ("props") that must be given on the construct -> because it is a react class, react will call internally something like

new MyButton(props);

He will always give you the props object into the instantiated Component. Now, by extending this existing react component class, you must achieve the same - or you will end up missing your "props" object. To make it possible, that one can still pass "props" to your newly defined component, you have to define the props also on your constructor, so you have to write this:

constructor(props: myProps) { .. }

Otherwise, you can't pass anything when you call "new MyButton(props)" -> well, this will not except or bring an error, but "props" will just be "null" in your further code of "MyButton".

Last but not least - you have to call the "super" in an extended version.

super(props);

Otherwise, you won't pass the given "prop" object to the basic class which you're extending from. Here, it could work too without it, but - then "props" will be "null" in any code of "React.Component" itself.

So, yes it is needed!

Basically you can answer this question yourself by simply using a debugger - just open your web-dev tools, jump to your component code, make a breakpoint in your constructor and watch closely what is happending and what is passed ;) Then, delete the property in the constructor once.. and remove the super call once... how will it except/break apart? ;)

Update:

The other question you can always ask yourself when creating new react components: do i need state? do i need lifecycleHooks?

If one of those is yes, you'll have to extend from React.Component - because only the basic class is giving you this sugar. But as can say, no, i don't need any of those - always go with a StatelessComponent:

const MyComp = (props) => (
  <div></div>
)

And try to avoid local component states too - you can do much better with one global state trough react-redux and selectors ;)

jebbie
  • 1,418
  • 3
  • 17
  • 27
1

Constructor and Super are no longer necessary in react. State can be defined without a constructor and lifecycle hooks also work fine. This is a result of Babel transpiling the components that way: http://2ality.com/2017/07/class-fields.html

In traditional ES6 this is currently not the case.

Dog
  • 2,726
  • 7
  • 29
  • 66
1

Today, the constructor is needed only when you must initialize a component with a state from props.

import React from 'react'

class AChildComponent extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      myState: props.myStateFromProps
    }
  }

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

export default AChildComponent

Abraxas
  • 101
  • 2
  • 6