I was just experimenting and this got me confused. I don’t see why calling foo two times should affect output of the timeout callback from previous invocation. This code:
let state = {
age: 0
};
let getState = () => {
let setState = () => {
state = {
age: state.age + 1
}
}
return {
state,
setState
}
}
function foo() {
let {
state:st,
setState
} = getState();
replicaUseEffect = () => {
console.log("replicaUseEffect", st);
}
console.log("before", st);
setState()
console.log("after", st);
setTimeout(() => replicaUseEffect(), 1000)
};
foo();
produces following output which I am ok with more or less:
"before", {
age: 0
}
"after", {
age: 0
}
"replicaUseEffect", {
age: 0
}
Now, simply call foo twice instead:
foo();
foo();
And output is this:
"before", {
age: 0
}
"after", {
age: 0
}
"before", {
age: 1
}
"after", {
age: 1
}
"replicaUseEffect", {
age: 1
}
"replicaUseEffect", {
age: 1
}
Why calling foo two times affect both replicaUseEffect values in the second example and output 1 two times?
I tried also printing inside the console.log with JSON.stringify but result is the same.
>Solution :
The reason that both replicaUseEffect calls output the same value, is that replicaUseEffect has been defined as a global variable, and so the second call of foo replaces the previous version of replicaUseEffect with a new one. And although its code is exactly the same, it lives in a different closure, which has the st local variable of the second execution context of foo.
You don’t have this effect when replicaUseEffect is defined as a local variable:
let state = {
age: 0
};
let getState = () => {
let setState = () => {
state = {
age: state.age + 1
}
}
return {
state,
setState
}
}
function foo() {
let {
state:st,
setState
} = getState();
const replicaUseEffect = () => {
console.log("replicaUseEffect", st);
}
console.log("before", st);
setState()
console.log("after", st);
setTimeout(() => replicaUseEffect(), 1000)
};
foo();
foo();