const { useState, useCallback } = React;
let globalValue = 0;
const ComponentA = ({ propValue }) => {
const [sum, setSum] = useState(propValue);
const [stateValue, setStateValue] = useState(0);
const onClick = useCallback(() => {
console.log(propValue, stateValue, globalValue);
setSum(propValue + stateValue + globalValue);
}, []);
return (
<div>
<p>State value is {stateValue}</p>
<p>Sum is {sum}</p>
<button onClick={() => setStateValue(stateValue + 1)}>
Set stateValue
</button>
<button onClick={() => globalValue += 1}>
Set globalValue
</button>
<button onClick={onClick}>
Get Sum
</button>
</div>
);
};
const Parent = () => {
const [propValue, setPropValue] = useState(0);
return (
<div>
<p>Prop value is {propValue}</p>
<button onClick={() => setPropValue(propValue + 1)}>
Set PropValue
</button>
<ComponentA propValue={propValue} />
</div>
);
};
If the dependencies list for useCallback in ComponentA is set to [], when the console.log is executed, no matter what the current propValue and stateValue are, they will always be 0. But the globalValue will always use the latest. When I check the __proto__ of propValue and stateValue, both of them are just primitive type.
How does useCallback hook keep the variables' original values? Shouldn't it respect the rule that if a variable is not defined in the current scope, it will look up to its parent and use the value from there (like globalValue)?
I understand that's the point of useCallback/useMemo but how is this implemented?