- Shipped
- 26 Agosti 2026, 02:40 UTC
- Author
- kamo
- Commit
- d8ab7f4
UnreadContext published a fourteen-member object literal as its context value, so React saw the context change on every render of the provider and woke every consumer to hand them the same counts. It is mounted app-wide inside AuthedChrome and read by the nav badges, the chat surfaces and the hex heads, so "every consumer" is a wide fan. All fourteen members are useCallback'd or derived state, so memoizing changes the value only when something a consumer can actually see has moved. VirtualMessageList's load-more effect listed `virtualizer.getVirtualItems()` in its own dependency array. That method builds and returns a NEW array on every call, so the dependency was a fresh reference on every render and the effect re-ran every time, re-comparing indices it had already compared — in the message list, on every scroll frame. What it actually depends on is how far the list has been scrolled, which is one number; it depends on that number now. The same call is also reused for the rows instead of being made a second time further down the render. Verified: tsc --noEmit clean over UnreadContext, VirtualMessageList and AuthedChrome with their transitive imports; all 9 guards pass; 36 tests across the chat and messages suites pass.