Reputation: 11830
suppose we have a handler (inside our class extends component in react)
whatever = () => {
//Something
}
when we do
onClick="{()=> this.whatever}"
, as javascript process our code (or compile/read) this won't be executed until the click event happens
In contrast
{this.whatever} should be executed as soon as javascript reaches this point or reads this.
Hence, we generally use this {()=> this.whatever}
we want event to happen after someone say click? and {this.whatever}
will execute handler/method immediately when JS compile?
[Update]
In a react application I was making by following some tutorial, we have arrow function handler say whatever
which pass to child component like this <BuildControls whatever={this.whatever} />
. Here in child component we do <button onClick={props.whatever} />
which works. So why didn't we do <button onClick={() => props.whatever} />
(also the onClick event doesn't work if we follow later approach)
Upvotes: 3
Views: 339
Reputation: 24660
{this.whatever}
is not same with {this.whatever()}
In javascript (and most of other languages) to execute a function you need parenthesizes. If you use {this.whatever}
you pass down a function as a parameter to a prop and when user clicks the passed function will be fired.
Below is the sample code showing difference.
const whatever = () => {
return "I log from function";
}
console.log(whatever); // returns function
console.log((() => whatever)); //returns a function that returns a function
console.log(whatever()); // runs the function
Sample React App (Live Demo)
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class CustomButton extends React.Component {
render() {
console.log("passed function", this.props.onButtonClick);
return (
<button
onClick={e => this.props.onButtonClick(e, "something from button")}
>
{this.props.name}
</button>
);
}
}
class App extends React.Component {
constructor() {
super();
this.test1 = this.test1.bind();
}
test1(e) {
// I'm a regular function
// I need to be bind
e.preventDefault();
console.log("test 1");
}
test2(e) {
// I'm a regular function
// I need to be bind
e.preventDefault();
console.log("test 2");
}
test3 = e => {
// I'm an arrow function
// I don't loose context of this
// so I don't need to be bind
e.preventDefault();
console.log("test 3");
};
test4 = (e, text) => {
// I am passed down to child component
// run with an extra argument
e.preventDefault();
console.log(text);
};
render() {
return (
<div className="App">
<button onClick={this.test1}>Test 1</button>
<button onClick={this.test2.bind(this)}>Test 2</button>
<button onClick={this.test3}>Test 3</button>
<CustomButton onButtonClick={this.test4} name="Test 4" />
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Some Documentation to read
Upvotes: 6
Reputation: 2685
{this.whatever}
is fine as long as the function it calls looks like
whatever = () => {
//Something
}
{this.whatever()}
would get called immediately.
Its better to write a separate ES6 function so it doesn't cause the function to be rewritten everytime the page is re-rendered.
Upvotes: 2
Reputation: 4260
Both commands mean the same thing.
But onClick={() => this.whatever()}
consumes more resources because every render
call reinstantiates that function.
You want to use the arrow function whenever you need to consume the argument
onClick={event => this.whatever(event)}
Upvotes: 1