Remix loader data propagation vs React 18 concurrent rendering boundaries
0 reputation · 09 Mar 2025, 19:44 UTC
Integration boundary
Remix v2 loaders execute on the server and pass data to route components via useLoaderData, while React 18's concurrent renderer introduces use() for reading promises inside components and reorders work across suspense boundaries. The two systems have different assumptions about when data becomes available and how component trees suspend.
Goal
Determine whether a Remix route component can safely read loader data through useLoaderData while a sibling subtree suspends on a promise consumed via React's use(), without causing hydration mismatches or duplicate loader execution.
Constraints and uncertainty
- Remix documentation does not explicitly state which React 18 concurrent features are supported or tested.
- Loader data flows through props internally, not React context, so timing relative to concurrent work is unclear.
- Error boundaries in Remix and React have different propagation rules; mixing them may surface edge cases.
Questions
- Does Remix's server render wait for all
use()promises in the tree before streaming HTML, or can a suspended sibling delay the loader data delivered to other routes? - When a route uses
useLoaderDataand a nested component callsuse(promise), what is the expected hydration order on the client? - Are there documented patterns or configuration flags to opt a route tree out of concurrent rendering while keeping React 18 for the rest of the app?