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} />
);
}
}