Edgar
Edgar

Reputation: 6856

Why x.func1 x.fun2 x.func3 functions do not work in onClick

This my code

function App() {
  const x = {
    value: 10,
    func1() {
      console.log(this.value, "111");
    },
    func2: function() {
      console.log(this.value, "222");
    },
    func3: () => {
      console.log(this.value, "222");
    }
  };
  return (
    <div>
      <h1 onClick={x.func1}>1</h1>
      <h1 onClick={x.func2}>2</h1>
      <h1 onClick={x.func3}>3</h1>
    </div>
  );
}

I created an object X, it has 3 functions func1, func2, func3. Why x.func1, x.fun2 x.func3 functions do not work in onClick ?.

Upvotes: 1

Views: 64

Answers (2)

Ori Drori
Ori Drori

Reputation: 191976

Because func1 and func2 are not bound to x, and when called as event handlers, this is undefined. func3 is an arrow function, and gets this from the enclosing lexical scope, which is the App function. The this value of a function depends on wether or not it's called in strict mode - see Function Context on MDN.

Point to x instead of this:

function App() {
  const x = {
    value: 10,
    func1() {
      console.log(x.value, "111");
    },
    func2: function() {
      console.log(x.value, "222");
    },
    func3: () => {
      console.log(x.value, "222");
    }
  };
  return (
    <div>
      <h1 onClick={x.func1}>1</h1>
      <h1 onClick={x.func2}>2</h1>
      <h1 onClick={x.func3}>3</h1>
    </div>
  );
}

ReactDOM.render(
  <App />,
  root
)
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

Example of arrow function on a literal object:

const x = {
  func3: () => {
    console.log(this === window); // this points to the enclosing lexical scope, which is window
  }
};

x.func3();

Upvotes: 1

alex067
alex067

Reputation: 3281

This is the classic problem of this binding in Javascript.

For each function, why don't you try to console.log(this) and you'll see that this is actually bounded to the window, rather than the object instance of x.

You have two solutions:

Redefine each function as an arrow function, so this is appropriately assigned to the parent object, which is x in this case.

Or, you may use bind:

<h1 onClick={func3.bind(x)}>3</h1>

Upvotes: 0

Related Questions