Skip to content

Instantly share code, notes, and snippets.

@jonidelv
Last active March 23, 2019 15:58
Show Gist options
  • Save jonidelv/52f7753e7288fddff1faff330fd3146a to your computer and use it in GitHub Desktop.
Save jonidelv/52f7753e7288fddff1faff330fd3146a to your computer and use it in GitHub Desktop.

Why do we use the constructor in React ES6 class components ?

Basically for 2 things:

  • For initialize our state with data (sometimes data that is passed through props).
  • For biding methods (which you shouldn't be doing, because of the new ES6 arrow function that don't create a new scope, so the this is "already binded").

What if I tell you that using the constructor is not longer necessary because of this class proposal that at the moment is in stage 3.

So this is possibble beause babel does it for you, it transpile your code and add a constructor for you. Here are some examples:

Initialize our state:

  • Before:
class Test extends Component {
  constructor() {
    super()
    this.state = { name: joni }
  }
  render() {
    const { name } = this.state
    return (
      <div>Name: {name}</div>
    );
  }
}
  • Now:
class Test extends Component {
  state = { name: joni }
  render() {
    const { name } = this.state
    return (
      <div>Name: {name}</div>
    );
  }
}
  • What babel is really doing:
class Test extends Component {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.state = { name: joni }, _temp;
  }

  render() {
    const { name } = this.state;
    return React.createElement(
      "div",
      null,
      "Name: ",
      name
    );
  }
}

Initialize our state with props:

  • Before:
class Test extends Component {
  constructor(props) {
    super(props)
    this.state = { name: this.props.name }
  }
  render() {
    const { name } = this.state
    return (
      <div>Name: {name}</div>
    );
  }
}
  • Now:
class Test extends Component {
  state = { name: this.props.name }
  render() {
    const { name } = this.state
    return (
      <div>Name: {name}</div>
    );
  }
}
  • What babel is really doing:
class Test extends Component {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.state = { name: this.props.name }, _temp;
  }

  render() {
    const { name } = this.state;
    return React.createElement(
      "div",
      null,
      "Name: ",
      name
    );
  }
}

Binding Methods:

  • Before:
class Test extends Component {
  constructor() {
    super()
    this.handleClick = this.handleClick.bind(this)
  }
  handleClick() {
    console.log('click')
    // some code here that references this
  }
  render() {
    return (
      <button onClick={this.handleClick} />
    );
  }
}
  • Now:
class Test extends Component {
  handleClick = this.handleClick.bind(this)
  handleClick() {
    console.log('click')
    // some code here that references this
  }
  render() {
    return (
      <button onClick={this.handleClick} />
    );
  }
}
  • What babel is really doing:
class Test extends Component {
  constructor(...args) {
    var _temp;

    return _temp = super(...args), this.handleClick = this.handleClick.bind(this), _temp;
  }

  handleClick() {
    console.log('click');
    // some code here that references this
  }
  render() {
    return React.createElement('button', { onClick: this.handleClick });
  }
}

Remember you should be using arrows functions here:

class Test extends Component {
  handleClick = () => {
    console.log('click')
    // some code here that references this
  }
  render() {
    return (
      <button onClick={this.handleClick} />
    );
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment