v6.4: How to show Pending UI in case of slow loader #8914
-
Super excite about v6.4 release and now I'm migrating my project to use Is there a way to show Pending UI when the loader is loading ? Here is the demo. similar to the demo in v6.4 release, but with the delay on |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 28 replies
-
export default function Root() {
const notes = useLoaderData();
const { state } = useNavigation();
return (
<>
{state === 'loading' && (
<progress
style={{
position: 'absolute',
top: '0',
left: '0',
width: '100vw',
}}
/>
)}
<div style={{ display: 'flex' }}>
{/* same code as before */}
</div>
</>
);
}``` |
Beta Was this translation helpful? Give feedback.
-
I'm trying to do the same thing so I'll reiterate the question asked. I've got this example that has a home page and about page: When I navigate to the about page which has an artificially delayed The problem is it seems the route does not render my "page" component until its Adding to that also seems the |
Beta Was this translation helpful? Give feedback.
-
I've played a bit more with those loaders, and the above approach is okay in some cases. The problem is when I want to render a different skeleton per route - that was what I originally tried to solve. Here's what I've come up with so far:
https://stackblitz.com/edit/github-tyjpmp-n9rngm?file=src%2Fmain.jsx Note: for some reason when I edit something and save I'm getting this |
Beta Was this translation helpful? Give feedback.
-
Yep https://beta.reactrouter.com/en/dev/guides/deferred Also FWIW, the other idiomatic approach (before |
Beta Was this translation helpful? Give feedback.
-
Before filing my own ticket, I followed this pattern of I tried using |
Beta Was this translation helpful? Give feedback.
-
A little bit tangential to what others are discussing, but since this is the first google result for "react router data loader show progress"... I can't use suspense because I'm doing an old fashioned vite SPA, and not using a "suspense-enabled data source". As such, I did a very simple and kind of dumb solution: // global loading state (jotai)
export const loading = atom(0);
// root router layout
const Layout = () => {
const { state } = useNavigation();
const getLoading = useAtomValue(loading);
return (
<>
<>
<Outlet />
{/* floating progress bar at top of screen */}
{state === "loading" && <ProgressBar progress={getLoading} />}
</>
</>
);
};
// some route data loader
async function somePageLoader() {
getDefaultStore().set(loading, 0.1);
await someAsyncFunc();
getDefaultStore().set(loading, 0.2);
await someAsyncFunc();
// etc...
} If anyone knows a less naive way to do this, let me know. I guess it would be cool if a |
Beta Was this translation helpful? Give feedback.
-
Any suggestions on how to figure out if a route is within a certain parent or not?Is matchPath the best approach, or would you suggest something else? Any examples you could point me to?Thanks On 11 Jun 2024, at 16:16, Matt Brophy ***@***.***> wrote:
Would you want to open a PR to update the docs with some clarification?
Yep - currently if you want contextual loading indicators you would need to check again the useNavigation().location. In the future you'll be able to leverage useTransition and the exposed routing promises (https://github.com/orgs/remix-run/projects/5?pane=issue&itemId=62177552) now that React has introduced some first-class APIs for dealing with async operations.
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
If you are using RouterProvider, you can specify the fallbackElement directly. This way, you don't need to use the defer function, as the fallbackElement will be displayed until the loader function resolves the promise. |
Beta Was this translation helpful? Give feedback.
Yep
defer
is what y'all are looking for here - let us know if this solves your use cases :)https://beta.reactrouter.com/en/dev/guides/deferred
Also FWIW, the other idiomatic approach (before
defer
) would have been touseFetcher
in your components and show skeletons/data based on those calls which would give you the "render then fetch" behavior you're looking for, instead of the default "fetch then render" behavior.