Reputation: 87
I found in legacy code
componentDidMount = () => {
...
}
I know it is not valid, but it works. Now, I am curious what is the difference between this, and the right way
componentDidMount() {
...
}
Upvotes: 1
Views: 5836
Reputation: 591
Hi basically you can do it, but it's unnecessary and can also hurt performance. Because each time your function does an arrow operation, it has to create a new function object. So it's just an optimization choice.
Good threads and articles:
Upvotes: 8
Reputation: 6299
Arrow functions and function declarations in React work the same way as how they work in vanilla JS.
componentDidMount = () => {
// arrow function
and
componentDidMount() {
// function declaration
mean the same as these functions are class specific in React. But things get interesting when you see how arrow functions and function declarations behave when you create them and pass them as handlers to other components.
Take a look at this example
export default class Parent extends Component {
constructor() {
super();
this.state = {
time: new Date().toLocaleTimeString()
};
// no function binding necessary
}
updateTime = () => { // arrow function used here
this.setState({ // `this` here will be bound to Parent implicitely
time: new Date().toLocaleTimeString()
});
};
render() {
return (
<div>
<div>Parent: {this.state.time}</div>
<button onClick={() => this.updateTime()}>Button in Parent</button>
<Child
time={new Date().toLocaleTimeString()}
updateTimeHandler={this.updateTime}
/>
</div>
);
}
}
// updateTimeHandler will be implicitly bound
// to Parent's context
const Child = ({ time, updateTimeHandler }) => {
return (
<div>
<div>Child: {time}</div>
<button onClick={() => updateTimeHandler()}>Button in Child</button>
</div>
);
};
export default Child;
Now when you don't use arrow,
export default class Parent extends Component {
constructor() {
super();
this.state = {
time: new Date().toLocaleTimeString()
};
// you have to bind the function to this class
// if you don't, then `this.` in the method
// will execute in child's context and throw an error
this.updateTime = this.updateTime.bind(this);
}
updateTime() { // function declaration
this.setState({
time: new Date().toLocaleTimeString()
});
}
render() {
return (
<div>
<div>Parent: {this.state.time}</div>
<button onClick={() => this.updateTime()}>Button in Parent</button>
<Child
time={new Date().toLocaleTimeString()}
updateTimeHandler={this.updateTime}
/>
</div>
);
}
}
// updateTimeHandler will execute in Parent's context
// as we explicitly told so
const Child = ({ time, updateTimeHandler }) => {
return (
<div>
<div>Child: {time}</div>
<button onClick={() => updateTimeHandler()}>Button in Child</button>
</div>
);
};
export default Child;
You can play around in this code sandbox and see it for yourself.
https://codesandbox.io/s/j78y87npkv
In addition to this behavior, there are obvious performance differences as quoted in other answers.
Upvotes: 0
Reputation: 720
I don't think there is much difference.
But () => {}
returns something (implicitly), and I don't think componentDidMount()
returns something nor would it be 'better'
So I would write this (as in the docs)
componentDidMount() {
...
}
Upvotes: 0