I am trying to understand how transitions work in React. Everytime I read the docs, I get a reasonable understanding but when I experiment with it, the understanding breaks down. I am unable to consistently predict its behaviour. Can someone please explain why the below code works in a certain way -
export default function App() {
const [count, setCount] = useState(0);
const [optimisticCount, setOptimisticCount] = useOptimistic(count);
const handleClick = async () => {
startTransition(async () => {
setOptimisticCount((prev) => prev + 1);
await new Promise((resolve) => setTimeout(resolve, 1000));
// startTransition(() => { // commented intentionally
setCount((prev) => prev + 1);
// });
});
};
console.log(
"Rendered with count",
count,
"and optimistic count =",
optimisticCount,
);
return (
<div>
<button onClick={handleClick}>Increment</button>
<p>Count is {count}</p>
<p>Optimistic Count is {optimisticCount}</p>
</div>
);
}
I expected the output to be
Rendered with count 0 and optimistic count = 0
Rendered with count 0 and optimistic count = 1
Rendered with count 1 and optimistic count = 1
But it's actually
Rendered with count 0 and optimistic count = 0
Rendered with count 0 and optimistic count = 1
Rendered with count 1 and optimistic count = 2 <-- Why does this happen?
Rendered with count 1 and optimistic count = 1
Note - If I follow React's recommendation to use another startTransition for any set calls after await statement within a startTransition, the code works as expected.
I am trying to understand the internal working of transitions and why omitting the additional startTransaction changes the output.