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
doSomethingconsole logs the statetestas it is initially is set, namelyundefinedwhereas 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?