> Requires a lot of coordination code, duplication, and coupling of your entire component hierarchy to each other no?
It's basically the Law of Demeter applied to UI components, and has both the benefits and the pitfalls of the LoD:
https://en.wikipedia.org/wiki/Law_of_Demeter
Boilerplate code goes up, method signatures get duplicated more (though JS has easy varargs & spread operators, so this can be minimized), method logic is less duplicated, and coupling is decreased.
> Still doesn't solve disparities in data loading completion across different services. Render giant loading spinner or the entire app?
You have a choice depending on product concerns. You can render a single loading spinner for the app. You can render individual spinners for different loading components (just pass the 'loading' prop into each of them separately), but have them all resolve at the same time. Or you can issue separate RPCs for each, as if the component had made the request itself, and have each component re-render as the request comes back.
The nice thing is that this choice is not embedded within the component itself, so you could for example start out by rendering a single global spinner until a single global RPC comes back, and then as you build out the backend and separate calls into different RPCs, change component rendering to incrementally show the new data.
> Plus, you will be overfetching if everything is pulled into top level components.
Again, this is a product tradeoff. Do multiple components display data that changes when an event happens on one component? It makes sense to batch up the RPCs then, because they'll always be triggered together anyway. Or is each component displaying data that is manipulated only by that component? Then give it its own RPC, but you should still kick it off at the top-level and delegate up the tree so that you can change this behavior easily.
In my experience, UIs designed by frontend engineers tend to have lots of RPCs that are both kicked off by and only affect a single component, while UIs designed by UI designers and CEOs (and users themselves) tend to have a lot of non-local changes throughout the UI in response to an event in one component. This is a source of tension between these groups, but only one side is signing the paychecks.