Second concrete adoption of proposal #2 (first was OfferView).
Before
- A useState<RoomEntryData[]>([]) for availableRooms.
- A useMessageEvent<RoomAdPurchaseInfoEvent> handler that
set the state on each parser event.
- A useEffect on mount that dispatched two composers, one of which
was GetRoomAdPurchaseInfoComposer paired with the parser above.
After
- A single useNitroQuery call wires the request and parser as one
read-only query. The select extracts parser.rooms with a default
empty array.
- staleTime is 60s — opening the same panel within a minute reuses
the cached value; the composer is not re-dispatched. Useful here
because the user navigates between catalog tabs.
- The mount-only useEffect no longer dispatches the room-ad composer;
the second composer (GetUserEventCatsMessageComposer) stays where
it was — that one feeds useNavigator state and isn't a
request-response pair this component owns.
Why this file
- It was the cleanest pattern in the catalog tree: no correlation
keys, no conditional filter on the parser, no other writes to
availableRooms. The pure derive-from-event case useNitroQuery is
built for.
- The big god-hook useCatalog (1100 LOC) still owns most of the
catalog data layer; migrating that needs the data/uiState/actions
split first.
Verification
- yarn test: 49/49 still passing.
- yarn eslint on the touched file: 1 error (the pre-existing
set-state-in-effect on line 36, unchanged — baseline matches).
- The previous useMessageEvent import was removed cleanly.