React version: 18.1.0
This issue may be a bit similar to this one: #24365
Steps To Reproduce
Code Example
The following example sets the toggle to on when the count is updated and creates a microtask and sets the toggle to off, we can see the toggle log every time it renders.
const [toggle, setToggle] = useState()
const [count, setCount] = useState(0)
useEffect(() => {
setToggle('on')
Promise.resolve().then(() => {
setToggle('off')
})
}, [count])
useEffect(() => {
console.log(toggle)
})
return (
<div className="App">
<button onClick={() => setCount(count + 1)}>refresh</button>
</div>
)
Weird things (steps):
- Refresh the page, it prints
undefined, undefined, on, off, so we know it's not batched.
- Click the button to update
count, it prints off, so we know it's batched.
- Change
useEffect to useLayoutEffect, and refresh the page, it's the same as step1 results, and click the button, it prints off, on, off, this result is very different from step2.
I think it's not normal because of inconsistent behavior.
Link to code example:
Same code in React18: https://codesandbox.io/s/react18-batching-problem-jtehj4?file=/src/App.js
Same code in React17: https://codesandbox.io/s/react17-batching-foo6fi?file=/src/App.js