100 Club
Props hitting at 100% over the selected window — the one board with a right rail of its own, and a watchlist that stopped being a second copy of server state.
/100-club · src/composed/hundred-club
Props that have hit in every game of the selected window. Three requests: the league picker, the screener query, and the watchlist.
The watchlist was a cache with no invalidation
It used to be a useState array kept in step by hand —
setWatchlist(prev => prev.filter(...)) after a DELETE,
setWatchlist(prev => [...prev, prop]) after a POST. Two tabs, or one failed
request, and it silently disagreed with the server.
It is now an SWR key that the mutations revalidate. The rule it stands for: if you are updating an array to match what you just told the server, you have written a cache, and caches need invalidation rather than bookkeeping.
It has the right rail
One of two routes that do — Home is the other. The rail is mounted at
app/(dashboard)/@rightSidebar/100-club/page.tsx; every other route resolves to
the slot's default.tsx, which returns null.
The rail's content is the board's, portalled in: the selected row, the watchlist and the query the rows came from are all state the shell cannot see. Architecture has the split.
Rows survive a filter change
The board is read on the server and arrives as props. What stops it blanking while a filter change is in flight is the transition the nuqs write runs in: React keeps the current rows on screen until the new ones are ready, rather than rendering an empty table for a round trip.