The React code is executed as you expected (the loop finishes first, the state is updated second), but
the browser console output is delayed.
Delayed console logs
The browser console is a quite sophisticated tool these days, with syntax highlighting and many
powerful assisting functionality.
The browser console doesn't simply execute a console.log()
synchronously, but only
recognizes that you want to print this value at this point in the code execution.
From this information, the console output is built "as quick as possible" in parallel to the main
code execution, often formatted or modified according to what the browser deems helpful.
But if the printing into the console takes a lot of time, the main code always has priority,
and the console output might become delayed, or even outdated.
You can add time stamps to verify this:
export default function App() {
const [count, setCount] = React.useState(0);
const eventHandler = () => {
setCount( prev => prev + 1 );
for( let i = 0; i < 1000; i++ ){
console.log( performance.now(), i );
}
console.log('end');
};
return (
<div>
<button onClick={eventHandler}>Click me</button>
<p>count: { count }</p>
<p>now: { performance.now() }</p>
</div>
);
}
You will notice that the last timestamp in the console is lower than the timestamp on the page, even
if the console prints it later.
Outdated console logs
For fun, you might want to play with this example:
const x = {
data: 'some data',
};
console.log('x:', x);
const MyApp = props => {
x.data = 'other data';
return <button onClick={ () => {
x.data = 'other data 2';
}}>
change x
</button>;
};
You might expect x.data
to be some data
, the value at the time the console.log
was executed.
And probably you will indeed see Object { data: "some data" }
in the console,
but if you expand the object in the console, it will (probably) display data: "other data"
.
But it's not as easy as "the console just keeps a reference to the object". E.g.
if you expand the object, the object stays fixed from there on, i.e. if you
click the button "change x" now, the value stays data: "other data"
.