T
TanStack•15mo ago
foreign-sapphire

Pending Component not working properly!

After trying things out looks like if i make the load function async it works! And renders the pending component:
loader: async ({ context }) => {
console.log("waiting...", context);
await sleep(5000);
console.log("done waiting");
return {
isAuthenticated: false,
};
},
loader: async ({ context }) => {
console.log("waiting...", context);
await sleep(5000);
console.log("done waiting");
return {
isAuthenticated: false,
};
},
But for the before load function it still behaves the same! Even though I pass async functions. But beforeLoad time should also be considered for waiting! Becuase without before load we are not given any option to update the router context! What do I do now? becaase i was needing to share my fetched session via context! and not by calling the tanstack use query everytime!
5 Replies
foreign-sapphire
foreign-sapphireOP•15mo ago
It was an urgent need ! Any help is really appreciatable.
environmental-rose
environmental-rose•15mo ago
Just to confirm, is this about the beforeLoad callback or the loader callback? And I'm assuming you need the pendingComponent to be shown for both cases yes? The beforeLoad callbacks all happen in serial, while the loaders are fired off in parallel. What you are facing may be a new issue. We'll need a working reproduction of this in a github issue I think 🤔
foreign-sapphire
foreign-sapphireOP•15mo ago
export const Route = createFileRoute("/employee/_sidebar")({
beforeLoad: () => {
sleep(6000);
return {
someData: "some data",
};
},
loader: () => {
console.log("waiting...");
sleep(5000);
console.log("done waiting");
return {
isAuthenticated: false,
};
},
pendingComponent: () => <div className="h-[95vh] bg-green-800 text-white">Loading...</div>,
component: SidebarLayout,
});
export const Route = createFileRoute("/employee/_sidebar")({
beforeLoad: () => {
sleep(6000);
return {
someData: "some data",
};
},
loader: () => {
console.log("waiting...");
sleep(5000);
console.log("done waiting");
return {
isAuthenticated: false,
};
},
pendingComponent: () => <div className="h-[95vh] bg-green-800 text-white">Loading...</div>,
component: SidebarLayout,
});
This is the code to regenerate the issue. 1. one thing is it needs to be an async function for the loader to trigger the pending component. 2. It doesn't execute parallel even though both the functions are async. I have come to know that from the logs. Keep your dev terminal open and hit reload you will say it prints before load then it waits n secs then it prints load then waits n secs again.
(Moreover parallel execution is also not the case here obviously because beforeLoad has the power to change the router context before getting it inside loader)
(Moreover parallel execution is also not the case here obviously because beforeLoad has the power to change the router context before getting it inside loader)
3. It always needs a load function for the top level pending component to trigger.for example I have 2 routes /Employee /Employee/login /Employee/_LayoutA /Employee/_LayoutA/_LayoutB So if I am loading something in layout A but want to put the pending component in /employee it doesn't work. this is specially noticable when you try to go to that loading page from another page and your pending component is on top level without a dummy async loader.It only works when I keep a empty async loader function along with the pending component in /employee. Well I have solved my problems as the way i mentioned above moved everything from beforeLoad to keep things consistent . And used a dummy async for getting the dummy component from the top level component so that I don't need to implement that spinning all the time in all nested layouts. But it was really tiring to spend the whole day in this last situation. So it's your wish now to fix this weird stuff of the library working or let the developers struggle.
wise-white
wise-white•15mo ago
It doesn't execute parallel even though both the functions are async.
https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#the-route-loading-lifecycle
So if I am loading something in layout A but want to put the pending component in /employee it doesn't work.
This isn't how it works. Considering the two routes
/Employee
/Employee/_LayoutA
/Employee
/Employee/_LayoutA
If you put the pendingComponent in /employee, it will be unmounted as soon as that route's beforeLoad/loader is done. Children routes states don't affect pending state of parents. If you want that route to be pending, it means that the request should be done at /employee route level (or you could show a different pendingComponent on the child route) I did face issues with pendingComponents in past versions but none on latest. But yeah, it's hard to correctly understand your issue without a reproduction template.
genetic-orange
genetic-orange•15mo ago
beforeLoad: () => {
sleep(6000);
return {
someData: "some data",
};
},
beforeLoad: () => {
sleep(6000);
return {
someData: "some data",
};
},
that's just a synchronous function that immediately returns the object. It doesn't wait 6 seconds if that's what you expect. I guess sleep returns a promise, so you need to await it or do a .then chain.

Did you find this page helpful?