I'm having a hard time understanding how this
works inside an onClick
function. I made a small CodePen
example here.
const history = {
init() {
this.counter = 0
return this;
},
increment() {
this.counter++;
}
}
const a = Object.create(history).init()
const MyComponent = () => {
a.increment();
// a's context is lost in the onClick function, how to
// make this work?
return (
<>
<button onClick={a.increment}>
click to increment
</button>
<p>{a.counter}</p>
</>
)
}
I realize this
context is call-site specific, and it rebinds to the onClick
function and thus the context i need to make it work is lost. But i don't know how to fix that. I realize i could use lambda
syntax or refactor the object another way that avoids this
completely, but that would just be dodging the problem.
Anyone able to provide a solution and a quick answer of what is really going on?
You can set value of this
inside increment function using bind
function. You also need to update state of the component to re-render it.
Code
const history = {
init() {
this.counter = 0;
return this;
},
increment(setCounter) {
setCounter(++this.counter);
}
}
const a = Object.create(history).init();
const MyComponent = () => {
const [counter, setCounter] = useState(a.counter);
return (
<>
<button onClick={a.increment.bind(a, setCounter)}>
click to increment
</button>
<p>{a.counter}</p>
</>
)
};
See working example