-2

I am wondering why some function calls work without parentheses? How do you know when it is appropriate not to use parentheses after function name? See example below. Why doesn't the 3rd line not work?

onClick={this.validate} // why does function work here without parentheses?
onKeyPress={e => e.key === 'Enter' && this.validate()} // works
onKeyPress={e => e.key === 'Enter' && this.validate} // doesn't work
2
  • 3
    In the first line, this.validate is a function that is not being immediately invoked or called. It's being stored for later. The code says "when clicked, I want you to call this.validate". In the example on line 2, that's a totally different context. There, you actually want to call it because its return value is being evaluated as part of a boolean expression rather than stored for later use. Line three says, "is the key equal to "Enter" and is this function definition truthy?" which doesn't make sense here (although you may want to ask whether a function var is defined, i.e. truthy). Commented May 8, 2019 at 20:07
  • @yury I'm not sure if this duplicate is appropriate. Yes it is definetly a good read for the OP, however we might benefit from an answer taking JS / React into account. That the answer below received two upvotes is a clear indicator of that. Commented May 8, 2019 at 20:29

1 Answer 1

3

onClick is an attribute that takes a function - under the hood, React, when receiving <some-element onClick={someFunction}/>, saves someFunction for later (notice that it doesn't call the function), and then calls the function when the user clicks. Note that you can rewrite this as <some-element onClick={(...args) => someFunction(...args)}/>, if that makes more sense to you.

Now here's what happens when the user presses on an element where onKeyPress={e => e.key === 'Enter' && this.validate()} is present:

  1. The function e => e.key === 'Enter' && this.validate() is called
  2. e.key === 'Enter' && this.validate() is evaluated
  3. e.key === 'Enter' is evaluated. If it evaluates to true, then:
  4. this.validate() is called and evaluated as a boolean

Notice how it is slighly different than when onKeyPress={e => e.key === 'Enter' && this.validate} is written instead:

  1. The function e => e.key === 'Enter' && this.validate is called
  2. e.key === 'Enter' && this.validate is evaluated
  3. e.key === 'Enter' is evaluated. If it evaluates to true, then:
  4. this.validate is evaluated as a boolean. If the function exists, it is coerced into the boolean true, else this.validate evaluates to undefined, which is coerced into the boolean false. Notice how this.validate did not get called. I'd regard this as a bug, except if you expressively want this behavior to happen.
Sign up to request clarification or add additional context in comments.

3 Comments

Nothing is coerced into a boolean though.
Well, I was just trying to explain the algorithm on a high-level. Of course "coercion" and "cast" are not exactly true, IMO but they explain what's happening.
No, thats not happening at all. Functions are just truthy. Nothing is casted or coerced into a boolean. Actually if e.key === "Enter" is truthy, the last part will just be evaluated and returned.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.