S
SolidJS2mo ago
anthy

"Simulating" loading state with createAsync

Here's a very simplified example what I'm trying to achieve:
import { createAsync, query } from '@solidjs/router';
import { Suspense } from 'solid-js';

function DataDisplayer(props: { data: string | undefined }) {
return <div>{props.data ?? 'Data still loading'}</div>;
}

const getData = query(async (): Promise<{ data: string }> => {
return await new Promise((resolve) => {
setTimeout(() => {
resolve({ data: 'hello' });
}, 1000);
});
}, 'getData');

export default function Home() {
const data = createAsync(() => getData());

return (
<main>
<Suspense fallback="Loading">{Boolean(data())}</Suspense>
<DataDisplayer data={data()?.data} />
</main>
);
}
import { createAsync, query } from '@solidjs/router';
import { Suspense } from 'solid-js';

function DataDisplayer(props: { data: string | undefined }) {
return <div>{props.data ?? 'Data still loading'}</div>;
}

const getData = query(async (): Promise<{ data: string }> => {
return await new Promise((resolve) => {
setTimeout(() => {
resolve({ data: 'hello' });
}, 1000);
});
}, 'getData');

export default function Home() {
const data = createAsync(() => getData());

return (
<main>
<Suspense fallback="Loading">{Boolean(data())}</Suspense>
<DataDisplayer data={data()?.data} />
</main>
);
}
In my real application the <DataDisplayer /> is a table that I want always rendered and I don't want to enclose it in a <Suspense />. If I were using createResource I would just use .loading. I found this hacky way of using Suspense, but it is pretty dirty. Is there any better way I can do what I want to do?
4 Replies
Madaxen86
Madaxen862mo ago
I think wrapping the table in Suspense and use data.latest is what you are looking for. It will display stale data while refetching . The fallback will just be shown during the initial request of the createAsync
anthy
anthyOP2mo ago
From within the table you can change params which will retrigger the query. And then I want the stale data in the table and the spinner on top Also isn't .latest to be removed?
peerreynders
peerreynders2mo ago
.latest was only added in 0.14.2 (August 2024)
GitHub
solid-router/CHANGELOG.md at main · solidjs/solid-router
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
peerreynders
peerreynders2mo ago
Just try using:
return (
<main>
<Suspense fallback="Loading">
<DataDisplayer data={data()?.data} />
</Suspense>
</main>
);
return (
<main>
<Suspense fallback="Loading">
<DataDisplayer data={data()?.data} />
</Suspense>
</main>
);
The query will always startTransition (transitions tutorial) which means it will paint hold the last render under the suspense boundary until the next render is ready. The suspense fallback will only appear the first time the query loads (i.e. when there is no previous render to hold). You can use the pending signal to drive a global loading indicator.
SolidJS
Solid is a purely reactive library. It was designed from the ground up with a reactive core. It's influenced by reactive principles developed by previous libraries.
Chrome for Developers
Paint Holding - reducing the flash of white on same-origin navigati...
A quick overview of paint holding. A Chrome feature for reducing the flash of white on same-origin navigations

Did you find this page helpful?