-1

This snippet came from a medium article. Why does the first <button onClick={this.handleClick1()}>click 1</button> have access to the actual properties in the class?

/**
 * Can you explain the differences between all those ways
 * of passing function to a component?
 *
 * What happens when you click each of the buttons?
 */
/**
 * Can you explain the differences between all those ways
 * of passing function to a component?
 *
 * What happens when you click each of the buttons?
 */
class App extends React.Component {

  constructor() {
    super(); 
    this.name = 'MyComponent';

    this.handleClick2 = this.handleClick1.bind(this);
  }

  handleClick1() {
    alert(this.name);
  }

  handleClick3 = () => alert(this.name);
render() {
    return (
      <div>
        <button onClick={this.handleClick1()}>click 1</button>
        <button onClick={this.handleClick1}>click 2</button>
        <button onClick={this.handleClick2}>click 3</button>
        <button onClick={this.handleClick3}>click 4</button>
      </div>
    );
  }
}
bresson
  • 581
  • 3
  • 18
  • 1
    It looks like you have typo(s) somewhere, `handleClick2` isn't being used, and `onClick={this.handleClick1()}` would execute the alert immediately on mount. It also looks like you're misunderstanding javascript scope based on your question, but it's unclear what your question is. There are no class properties in this component. – Andy Ray Jul 21 '19 at 03:40
  • Class declarations are just syntactic sugar on top of the object prototype. – Derek Jul 21 '19 at 03:40
  • I removed listener for handleClick2 to focus on handleClick1 ... it shouldn't have an effect on handleClick1 ... – bresson Jul 21 '19 at 03:41
  • You don't actually use `handleClick2` anywhere in your code. We could guess what you're trying to ask, but the question as written right now is kind of messed up and you're using some wrong terms to try to describe things. Please fix your question. – jfriend00 Jul 21 '19 at 03:42
  • I remove the other code to focus on handleClick1. The rest of the code isn't really necessary. – bresson Jul 21 '19 at 03:45
  • I put the full code back in – bresson Jul 21 '19 at 03:48
  • 1
    You would probably benefit from reading [The six ways the value of this is controlled in Javascript in function calls](https://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676). Several of them apply to your scenarios. – jfriend00 Jul 21 '19 at 04:12

2 Answers2

1

Why does the first <button onClick={this.handleClick1()}>click 1</button> have access to the actual properties in the class?

this.handleClick1() invokes the function right then and there, i.e. not when the event is triggered later. handleClick1 returns undefined so no event handler is actually bound.

And since the function is called as object property (x.y()), onClick1's own this value is set to the value before the . (also this).

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072
  • Excellent! This is the answer. Putting the execution inside a listener is just misdirection. Tricky .... – bresson Jul 21 '19 at 11:11
0

Because it is binded with this

this.handleClick2 = this.handleClick1.bind(this);

Function.prototype.bind

Code Maniac
  • 33,907
  • 4
  • 28
  • 50
  • But that binding is passed to handleClick2 isn't it? The very next click event, ``` ``` yields undefined – bresson Jul 21 '19 at 03:40
  • @bresson because you're assigning binded value to `this.handleClick2` not `handleClick1`, `this.handleClick1()` works because during initial render your `this` points to `MyComponent class` – Code Maniac Jul 21 '19 at 04:06