I have stumbled upon an issue that is very weird for me, but most probably is very simple to explain.
Demo
Let's assume the following React component
import React, { useState, useEffect, useCallback } from "react";
export default function App() {
const [test, setTest] = useState();
const doSomething = () => {
// TODO: Why does this returns the inital state value? Hoisting?
console.log(test);
};
const doSomethingWithCallback = useCallback(doSomething, [test]);
useEffect(() => {
setTest("asas");
window.setTimeout(() => doSomething(), 2000);
document.addEventListener("click", doSomethingWithCallback);
return () => {
document.removeEventListener("click", doSomethingWithCallback);
};
}, [doSomethingWithCallback]);
return (
<div className="App">
<h1>Click anywhere</h1>
</div>
);
}
(cf. CodeSandbox)
Question
Look at the TODO
comment in the code.
Why does
doSomething
console logs the statetest
as it is initially is set, namelyundefined
whereas the callback variant is returning it with the "real" current state when it is called?
Is this some kind of hoisting or performance optimization React is doing?