Reputation: 6856
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
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
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