Page content not updating on route change

I have the following page:
import { createAsync, useParams, type RouteDefinition } from '@solidjs/router';
import { Show, Suspense } from 'solid-js';
import { getInformationById } from '~/api';

export const route = {} satisfies RouteDefinition;

export default function InformationPage() {
const params = useParams();
const informationId = parseInt(params.id);
const information = createAsync(async () => getInformationById(informationId), {
deferStream: true,
});

return (
<main class='w-full p-4 space-y-2'>
<Suspense fallback={<p>Loading...</p>}>
<Show when={information()} fallback={<p>Loading...</p>}>
{(information) => (
<>
<h1>{information().name}</h1>
</>
)}
</Show>
</Suspense>
</main>
);
}
import { createAsync, useParams, type RouteDefinition } from '@solidjs/router';
import { Show, Suspense } from 'solid-js';
import { getInformationById } from '~/api';

export const route = {} satisfies RouteDefinition;

export default function InformationPage() {
const params = useParams();
const informationId = parseInt(params.id);
const information = createAsync(async () => getInformationById(informationId), {
deferStream: true,
});

return (
<main class='w-full p-4 space-y-2'>
<Suspense fallback={<p>Loading...</p>}>
<Show when={information()} fallback={<p>Loading...</p>}>
{(information) => (
<>
<h1>{information().name}</h1>
</>
)}
</Show>
</Suspense>
</main>
);
}
I navigate using this, which works for any other route, as it seems:
<a
href={'/information/' + information.id}
onclick={doSomeOtherStuff}
>
<a
href={'/information/' + information.id}
onclick={doSomeOtherStuff}
>
If any other information are needed, please @ me.
6 Replies
peerreynders
peerreynders6d ago
You are breaking reactivity:
const informationId = parseInt(params.id);
const informationId = parseInt(params.id);
Instead use
const information = createAsync(
async () => getInformationById(parseInt(params.id, 10)),
{
deferStream: true,
}
);
const information = createAsync(
async () => getInformationById(parseInt(params.id, 10)),
{
deferStream: true,
}
);
𝔐𝔞𝔱𝔱𝔦𝔫
Thank you, that works! Could you perhaps explain why that is?
Unknown User
Unknown User5d ago
Message Not Public
Sign In & Join Server To View
peerreynders
peerreynders5d ago
Unlike Svelte, in Solid code is just code, i.e. code is not reactive. It is up to you the developer to compose a reactive graph from the reactive primitives that Solid offers. Solid's reactivity is a runtime feature, not some compiler magic (apart from JSX being wrapped in a render effect). Within a component function there are two reactive elements: - the props which are similar to the proxy that is returned from createStore - the JSX which is wrapped in an implicit render effect. The component function itself is just a setup function (React component functions are render functions) and once it has executed it is up to the reactive graph that you constructed to keep the UI up-to-date. In the simplest case you could just reference the props inside the JSX (render effect); whenever a property on props changes, that change will be reflected inside the JSX render effect; this is why destructuring props breaks reactivity because destructuring simply copies the value (at the time of assignment) but it does not transfer reactivity to the assignment target. useParams() returns a reactive object.
const { id } = params;
const { id } = params;
would break reactivity
const informationId = parseInt(params.id);
const informationId = parseInt(params.id);
Is just a variation on the same theme. There is no destructuring here but it is just a simple assignment so reactivity is lost. Neither of this applies inside an effect function or a memo function. In that case the mere access to params is enough to subscribe to change propagation - kind of. But in order to target the change you are actually interested in you should stick with params.id in any case.
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
peerreynders
peerreynders5d ago
In the end you are managing: - referential stability for things that you confirm that haven't changed. - referential volatility for things on the level where you want change to be noticed. A derived value will just work inside a memo/effect function
But that should highlight that the component function itself does not execute in an environment that similar to an effect or memo function because it's just a setup function (there is no re-render); just the JSX is reactive due to the render effect it is wrapped in and the props can be reactive provided they are used within a reactive environment.
𝔐𝔞𝔱𝔱𝔦𝔫
Thank you very much for the detailed explanation. This helps me better understanding this topic. Very well written and understandable!
Want results from more Discord servers?
Add your server
More Posts