I'm convinced that React's concurrent rendering model is fundamentally at odds with fine-grained reactivity/updates/rerendering.
I have users who are clawing at me for fine-grained updates and rendering subscriptions in TanStack Router, but you simply can't have both fine-grained updates AND things like transition/suspense-aware state. Let me explain.
To get fine-grained subscriptions in react, you have to use an external store (literally anything that doesn't trigger rerenders out of the box) and wire up the subscriptions to where they are used in react, hopefully with something like selectors, proxies, signals or atoms. However, as soon as you move your state out of useState/useReducer, you will experience state tearing when you attempt to use concurrent rendering, especially with startTransition. This is because React can't "version" your state, create new fibers based on it, etc. So if fine-grained reactivity and subscriptions are important to your application or library, you kinda just have to swallow the bitter pill that you can't *really* support startTransition at the same time... and tell some of your users (who may totally *need* concurrent rendering, but refuse to use a library if it doesn't check that box) to take a hike.
Maybe you decide it's worth trying to figure out though, just like I did 2 months ago, so you can get that high-quality A-grade startTransition support people are asking you for. To do this, you must put ALL of your state into either useState or useReducer and ensure you're not breaking ANY concurrent rendering rules. However once you do this, you'll quickly realize the only way to propagate that state down to subscribers is via React context... So you start to do the song and dance of splitting your state into multiple contexts. But then you also realize that updating any useState or useReducer will trigger renders all the way down... unless you useMemo to bail out... and teach your users to do the same. At the end of the day, you essentially have to tell your users to embrace frequent rerenders and optimize the crap out of their entire application. But hey, that's not too different than what they're used to. But it's important that people realize this is the reason that the "useMemo as an optional optimization" speak is a bandaid lie we've been told to so we can deal with React's lack of reactivity.
So here I am with two patterns that are essentially at odds with each other and I'm on the verge of picking one over the other. Can you guess which one?
Is concurrent rendering - and more specifically in this case, holding paints until all suspense boundaries inside of your startTransition resolve - more important than fine-grained performance?
Why do we have to choose?