jadeite1000
jadeite1000

Reputation: 659

Why no parentheses on a function

Any help or hint would be greatly appreciated. Why don't use parenthese in method call? If I use parenthese "onInputChange()" the method is called when I loaded the page. After the call, if I type anything in the input box and click outside the "onInputChange()" method is not call.

If I don't use parenthese "onInputChange" the method is not called when I loaded the page, why is that so? But after load and I type something in input box and click outside the method "onInputChange" is call.

wrong way:

  <input type="text" onChange={this.onInputChange()} />

correct way:

<input type="text" onChange={this.onInputChange} />

SearchBar.js

import React from 'react';

class SearchBar extends React.Component {
  onInputChange() {
    console.log('onInputChange');
  }

  render() {
    return (
      <div className="ui segment">
        <form className="ui form">
          <div className="field">
            <label>Image Search</label>
            <input type="text" onChange={this.onInputChange()} />
          </div>
        </form>
      </div>
    );
  }
}

export default SearchBar;

Upvotes: 2

Views: 1317

Answers (2)

Rahul Sharma
Rahul Sharma

Reputation: 10071

If you use parentheses in the method it'll execute on render itself. It won't wait for the event to execute.

With parentheses: Assign result of the function to onChange event

Without parentheses: Assign a function to the onChange event

Plain javascript example

function onValueChange(){
  console.log("onValueChange");
}

function onValueChange1(){
  return onValueChange;
}
<button onclick="onValueChange()">Without Parentheses</button>

<button onclick="onValueChange1()()">With Parentheses</button>

Upvotes: 7

CertainPerformance
CertainPerformance

Reputation: 370699

When the code gets compiled from JSX to pure JS, many props are simply object properties. For example:

<input type="text" onChange={this.onInputChange()} />

This gets compiled to:

React.createElement("input", {
  type: "text",
  onChange: this.onInputChange()
});

Just like in ordinary JS, if you invoke a function directly inside the prop or object, that function will be invoked when the object is evaluated for the first time.

const fn = () => {
  console.log('fn running');
  return 'foo';
};
const obj = {
  prop: fn()
};
console.log('obj is', obj);

But you don't want to invoke the function immediately - you want to pass just a reference to the function so that React can invoke it, so you'd need the equivalent of

const obj = {
  prop: fn
};

in your code in the JSX, which is:

<input type="text" onChange={this.onInputChange} />

without the parentheses.

Note that you can do

<input type="text" onChange={() => this.onInputChange()} />

but that isn't invoking onInputChange immediately - rather, it's passing a function which, when called, invokes onInputChange.

Upvotes: 5

Related Questions