Bailouts for state updates behavior inconsistently for hooks
See original GitHub issueThis is a bug I think.
As the title says, React didn’t help me to merge the update requests.
const Player = ({ }) => {
const [name, setName] = useState('John Higgins',)
const [age, setAge] = useState(47)
const nextPlayer = () => {
setName('Mark Selby')
setAge(34)
}
console.log('render.')
return <p>
This player's name is {name}, {age} years.
<button type="button" onClick={nextPlayer}>next</button>
</p>
}
After the button clicked, it outputs:
>> render.
>> render.
But in fact, I got three.
>> render.
>> render.
>> render.
It doesn’t always be.
The actual code
const List = ({}) => {
const [items, setItems] = useState<ListItem[]>([])
const [tick, setTick] = useState(0)
const [page, setPage] = useState(1)
// # effect 001
useEffect(() => {
const refresh = tick > 1
load({ refresh, page })
.then(d => {
if (refresh) setItems(d) // replace
else setItems([...items, ...d]) // append
})
}, [tick, page])
// # effect 002
useEffect(() => {
testingScrollToBottom(() => {
setTick(0) // makes effect 001 applied.
setPage(page + 1) // makes effect 001 applied again.
})
return () => {
stopTestingScrollToBottom()
}
}, [page])
return (
<div>
<button
onClick={() => {
setTick(tick + 1)
setPage(1)
}}>
Refresh
</button>
{ items.map(item => <Item item={item}/>) }
</div>
)
}
Function testingScrollToBottom
is where the things happened.
Here is what I did to avoid that:
By the way, testingScrollToBottom
uses setTimeout
.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:12 (2 by maintainers)
Top Results From Across the Web
Could a Federal Loan Program Help Fix Ailing State Public ...
We have argued that a federal bailout of state pension plans is a bad idea for numerous reasons. But the calls for doing...
Read more >the arbitrary and inconsistent non-bank sifi designation ...
Yet, FSOC additionally fails to conduct any cost-benefit analysis when designating a firm as a SIFI. For this reason, the Oversight and ...
Read more >Treatment of Certain Interests in Corporations as Stock or ...
Congress added section 385(c) in response to issuers and holders characterizing a corporate instrument inconsistently. H.R. Rep. No.
Read more >Bug listing with status CONFIRMED as at 2022/12/26 10:46:31
status:CONFIRMED resolution: severity:enhancement · Bug:21509 - "[PATCH] [IDEA] ... Bug:45276 - "Req: ebuild for state threads" status:CONFIRMED resolution: ...
Read more >Change log : linux-aws-5.11 package : Ubuntu
MX8QXP" - net/mlx4_en: Update reported link modes for 1/10G - ALSA: hda: Add ... state in bringup_cpu() - f2fs: set SBI_NEED_FSCK flag when...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Just suffered from this issue, and am glad to see it’s already been reported and has been discussed.
Minimal Reproduction
Wanted to offer a minimal reproduction for anyone coming here trying to understand the issue, with setTimeout calling setter functions returned by
useState
hook, and React not merging (batching) those updates:Basically, clicking the button will trigger 3 renderings of the component (one for each
setState
function called from withinsetTimeout
), each rendering with only a partial state update.CodeSandbox: https://codesandbox.io/s/unexpected-renderings-with-incomplete-state-update-txhy7
React’s event batching does take things like this into consideration, but we wouldn’t want React to be in the business of overriding global/native APIs like
setTimeout
.FWIW the upcoming concurrent mode will automatically batch nearby state updates, like in the case you shared, so this wouldn’t have been an issue either.