Alwaysblue
Alwaysblue

Reputation: 11830

{()=> (this.whatever)} vs {this.whatever}

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

Answers (3)

bennygenel
bennygenel

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

nathan hayfield
nathan hayfield

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

Ramon Balthazar
Ramon Balthazar

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

Related Questions