S
SolidJS•6mo ago
hannus

Confusion about Preload mechanism

I am confused about the preload mechanism. According to my understanding, adding an asynchronous function wrapped by a cache in preload initiates data fetching when the route is accessed, ensuring the data is ready when the page starts rendering. Observing the console, this indeed happens. When the function is called within the route component, the data should already be prepared. Even if an asynchronous function calls this function, it should immediately return the data. However, my observation is different; there is still an asynchronous process to re-fetch the data. The sample code is as follows:
// function in the preload()
export async function handleUser(): Promise<void> {
"use server";
const userinfo = await fetchUserInfo("http://localhost:8000/getuserinfo/");
console.log("userinfo", userinfo);
if (userinfo === undefined) {
throw redirect("/login")
}
}

export const handleUserCache = cache(handleUser, "handleUser");

// in route component file

export const route = {
preload() {
handleUserCache();
}
} satisfies RouteDefinition;

export default function Auth() {
console.log("start auth page render")
const userinfo = createAsync(() => handleUserCache());
console.log("after async function")

return ....
// function in the preload()
export async function handleUser(): Promise<void> {
"use server";
const userinfo = await fetchUserInfo("http://localhost:8000/getuserinfo/");
console.log("userinfo", userinfo);
if (userinfo === undefined) {
throw redirect("/login")
}
}

export const handleUserCache = cache(handleUser, "handleUser");

// in route component file

export const route = {
preload() {
handleUserCache();
}
} satisfies RouteDefinition;

export default function Auth() {
console.log("start auth page render")
const userinfo = createAsync(() => handleUserCache());
console.log("after async function")

return ....
7 Replies
hannus
hannusOP•6mo ago
In the above code, when navigating to the Auth route (either by entering the route address in the address bar or hovering over the route link), the console shows the userinfo log, such as undefined when not logged in, which is as expected. Upon entering the route, the UI abruptly switches to the login route component. The console logs are executed before and after calling the asynchronous function. According to my understanding, when the component calls the asynchronous function already loaded in preload, it should use the preloaded data instead of reloading it. Therefore, my expectation is that the Auth component retrieves the data immediately and redirects without executing the console log after the asynchronous function, avoiding abrupt page changes. Am I doing something wrong?
Madaxen86
Madaxen86•6mo ago
Carefull with the console logs. They don't represent how many fetch calls are being made: Here's an example from an app: - First console log preload is from hovering the link - second log of preload is when loading the page - then we have to calls "refetch" which I have attached to the createAsync in the component... But from the network tab we can see that there's only one fetch call to the server (ignore the option call). I'm not deep into the internals of solid to explain how this happens, but I can tell you it's fine. It's the "magic" of the cache function.
No description
hannus
hannusOP•6mo ago
thanks. I get it. I'll be careful with console log and cache which is black box for me now 😉
Brendonovich
Brendonovich•6mo ago
preload initiates data fetching when the route is accessed, ensuring the data is ready when the page starts rendering
preload won't ensure the data is ready, it will just start fetching it. it's up to your component to use Show or Suspense or whatever else to wait until the data has loaded
hannus
hannusOP•6mo ago
thanks, if the function within preload has throw redirect() , is it possible to redirect before the component render?
Brendonovich
Brendonovich•6mo ago
if you read userInfo inside the JSX then you can use Suspense to show a fallback until the fetch has finished
hannus
hannusOP•6mo ago
got it, thanks a lot
Want results from more Discord servers?
Add your server