Wow, RxJS turns working with event streams in React from horrendous to awesome
(building a toy #nostr client)
* provides decent state management
* lots of functions for stream transformation
* avoids infinite re-render loops
* makes the code concise, declarative and much much much easier to reason about
* better performance
Example:
Got a stream of notes coming into the feed and you want to fetch the author profiles as they come in
So you've got an infinite stream of authors like dan, 8888, Beth, geodesic, Beth, Beth, Stacks, P2E, dan, BelleAme1618, BelleAme1618
And you want to create only one subscription for their profile events per author
And you want to batch authors into subscription requests
And you want the batches to be spaced 0.5 seconds apart
Batch 1: dan, 8888
Batch 2: Beth, geodesic, Stacks
Batch 3: P2E, BelleAme1618
So you can do...
notes$.pipe(
map(notes => getPubkeysFromEvents(notes)),
mergeAll(),
distinct(),
bufferTime(500),
filter(pubkeys => pubkeys.length > 0),
map(createAuthorFilters),
mergeMap(authorFilters => subscribeToEvents(pool, relays, authorFilters)),
);
By using RxJS for everything you can move all logic out of the component and just bind the RxJS streams to React state variables at the last moment for rendering
This seems to work better than minimalist use of RxJS where you end up lifting React state into RxJS observables
Binding to React state can be done with useObservableState from observable-hooks library or you can write a simple hook using useEffect
This is literally all that's in the component other than template code:
const notes = useObservableState(sortedNotes$, new Map() as EventsMap);
const authors = useObservableState(authors$, new Map() as UsersMap);