Patch Changes
-
Feat: adds
deferred
support to data routers (#9002)Returning a
deferred
from aloader
allows you to separate critical loader data that you want to wait for prior to rendering the destination page from non-critical data that you are OK to show a spinner for until it loads.// In your route loader, return a deferred() and choose per-key whether to // await the promise or not. As soon as the awaited promises resolve, the // page will be rendered. function loader() { return deferred({ critical: await getCriticalData(), lazy: getLazyData(), }); }; // In your route element, grab the values from useLoaderData and render them // with <Deferred> function DeferredPage() { let data = useLoaderData(); return ( <> <p>Critical Data: {data.critical}</p> <Deferred value={data.lazy} fallback={<p>Loading...</p>} errorElement={<RenderDeferredError />}> <RenderDeferredData /> </Deferred> </> ); } // Use separate components to render the data once it resolves, and access it // via the useDeferredData hook function RenderDeferredData() { let data = useDeferredData(); return <p>Lazy: {data}</p>; } function RenderDeferredError() { let data = useRouteError(); return <p>Error! {data.message} {data.stack}</p>; }
If you want to skip the separate components, you can use the Render Props
pattern and handle the rendering of the deferred data inline:function DeferredPage() { let data = useLoaderData(); return ( <> <p>Critical Data: {data.critical}</p> <Deferred value={data.lazy} fallback={<p>Loading...</p>}> {(data) => <p>{data}</p>} </Deferred> </> ); }
-
feat: add basename support for data routers (#9026)
-
fix: Fix trailing slash behavior on pathless routing when using a basename (#9045)
-
Updated dependencies
- @remix-run/router@0.2.0-pre.4