If you’ve used React for any serious development, you already know that it’s a few burritos short of a full Mexican fiesta. Both its tree-based prop and state management, and the complete lack of support for routing, have been pretty big gaps that have challenged a generation of developers. Here are my notes to self on finding a better path than what is suggested out of the gate.

React State Management

The need for frontend state is real, unless you made a read-only static webpage, and then you should have used HTML.

Default React state management is basically a cascading tree where the parent doles out bits of state to its children. Why is my client state rigidly baked into the structure of my UI? This naive approach doesn’t typically hold up for long.

Once I found the solution, it was like fresh oxygen. Make yourself a true data store, and manage your client state as it needs to be managed, entirely outside whatever you decide is the most intuitive UI to access that state. React now allows this, via useSyncExternalStore. It is trivial to write state setters and getters, and a clean pub/sub mechanism to broadcast changes precisely where they are needed.

React routing

React Router seems to have been cobbled together after React was delivered with nothing to offer. It didn’t happen in a straight, well-planned linear progression, that’s for sure.

Once again the default design bakes routing right into the UI elements. I can’t navigate unless I use a UI link literally scratched into the page? Fine if I’m making static text with hyperlinks. Not many people’s use case these days. But unfortunately, react-router was there early to poorly scratch the itch that React left untouched, so everyone adopted it and conformed to its opinionated approach. Approaches, really, as more band-aids were inevitably patched in.

Might as well use it, but I would not use the recommended <Link /> approach. Instead, navigate programmatically, after doing what needs to be done. Parts:

  • Maintain state of UI navigation in your datastore (eg, which components are visible)
  • Use typical Route with parameters
  • When processing user requests, take action, set state, then programmatically navigate as needed
  • To handle bookmarks, check params in component constructor, and use navigate if url params do not match datastore state

Maybe I’ll add code to this when I’m not so busy.