S
SolidJS•7mo ago
Xzayler

Navigating with A from and to dynamic route doesn't re-render.

I have a dynamic route routes/post/[postid].tsx. Within this route I have (simplified)
const [post, {mutate, refetch}] = createResource(() => {
return getPost(params.postid);
});
// I also tried running refetch() here
return
<A href={`/post/${item.id}`}>
// more jsx...
</A>
const [post, {mutate, refetch}] = createResource(() => {
return getPost(params.postid);
});
// I also tried running refetch() here
return
<A href={`/post/${item.id}`}>
// more jsx...
</A>
In dev, when I click on this a tag, the url updates in my browser but the dom doesn't, unless I force a reload. I'm guessing post doesn't refetch or something. Do I need to force a refetch somehow or am I navigating wrong?
24 Replies
Birk Skyum
Birk Skyum•7mo ago
StackBlitz
Solid-start Basic Example - StackBlitz
Run official live example code for Solid-start Basic, created by Solidjs on StackBlitz
Birk Skyum
Birk Skyum•7mo ago
You might have to use a cache instead of the createResource
Xzayler
Xzayler•7mo ago
Xzayler
StackBlitz
Solid-start Basic Example - StackBlitz
Run official live example code for Solid-start Basic, created by Solidjs on StackBlitz
Xzayler
Xzayler•7mo ago
I put that random div there so I can force a reload when I change it's contents. As you can see clicking the link won't update anything visually but the id does increment by one
Birk Skyum
Birk Skyum•7mo ago
The functionality of that example can be achieve by using a memo instead: https://stackblitz.com/edit/github-qx1qqd-mqqted?file=src%2Froutes%2Fpost%2F%5Bpostid%5D.tsx
Birk Skyum
StackBlitz
Solid-start Basic Example (forked) - StackBlitz
Run official live example code for Solid-start Basic, created by Solidjs on StackBlitz
Birk Skyum
Birk Skyum•7mo ago
But if it has to be with the createAsync I'll debug a bit more
Xzayler
Xzayler•7mo ago
Yeah I need to run a db fetch so it has to be async thank you
mdynnl
mdynnl•7mo ago
the reason why it doesn't work in the first example is createResource doesn't track in the form createResource(fn) as explained here https://docs.solidjs.com/reference/basic-reactivity/create-resource
Xzayler
Xzayler•7mo ago
Yeah it's why I tried using the refetch but I don't understand where to run it.
mdynnl
mdynnl•7mo ago
it's suggested to learn the basics createResource, etc before new router primitives like createAsync, cache pattern for createResource, the solution is just createResource(() => params.postid, ...)
Xzayler
Xzayler•7mo ago
Yeah tried that too, maybe not in the right way, I had
const [post] = createResource(params.postid, (id) => {
return getPost(id);
});
const [post] = createResource(params.postid, (id) => {
return getPost(id);
});
First load is always correct
mdynnl
mdynnl•7mo ago
this eagerly access params.postid it needs to be a signal (function) there's a hidden memo under the hood this is a really important and fundamental concept you should understand before any other concepts when you're working with solid
Xzayler
Xzayler•7mo ago
I am trying to understand and read the docs, in fact I tried this because I read this in docs: It [fetchData] will be called again whenever the value of source changes, and that value will always be passed to fetchData as its first argument. But the problem seems to simply be that the component isn't 're-run'. The body of the component's function doesn't reexecute. Navigating between the same dynamic route maybe is a more niche thing that I thought but I am assuming it can be done with basic a-tag navigation, having it execute as if it were a full on new page.
mdynnl
mdynnl•7mo ago
solid doesn't need to re-run the route component as it can update where only necessary it does this through signals and jsx transform signals being functions, and also any functions that indirectly call signals are also signals (usually called as derived signals) but they aren't reactive by themselves effects are what's reactive and signals are a mean to trigger the effects to rerun i'd just be reciting the docs though 😄 but let me know if you want me to continue technically the same thing as docs but it would be how i understand solid
Xzayler
Xzayler•7mo ago
Nah I actually got it.
const [post, { mutate, refetch }] = createResource(
params.postid,
(postid) => {
return getPost(postid);
}
);

createEffect(() => refetch(params.postid));
const [post, { mutate, refetch }] = createResource(
params.postid,
(postid) => {
return getPost(postid);
}
);

createEffect(() => refetch(params.postid));
createEffect was the solution
mdynnl
mdynnl•7mo ago
there's already a hidden memo inside createResource that uses the first param similar to how you're doing with effect so the solution is just a matter of wrapping params.postid with a function like so createResource(() => params.postid, getPost)
Xzayler
Xzayler•7mo ago
oooh! I though source was just a value!
mdynnl
mdynnl•7mo ago
😄 sorry for not giving out the solution as early as possible
Xzayler
Xzayler•7mo ago
No you gave it to me here but I didn't get it
mdynnl
mdynnl•7mo ago
i mean like createMemo(params.postid) wouldn't work i believe you have experience with a framework that uses jsx right? if so, although it's difficult, the best you can do is unlearn things
Xzayler
Xzayler•7mo ago
some next.js experience. And it'sprobably causing more bad than good with solid cuz I think I know stuff when i don't exactly Well thanks for the help I feel like this is gonna be very good to know in the future
Birk Skyum
Birk Skyum•7mo ago
If you managed to find a good solution, can you share a stackblitz with it for reference?
Xzayler
Xzayler•7mo ago
Xzayler
StackBlitz
Solid-start Basic Example - StackBlitz
Run official live example code for Solid-start Basic, created by Solidjs on StackBlitz
Xzayler
Xzayler•7mo ago
Basically, the pattern
const params = useParams();
const [post] = createResource(
() => params.updatingVal, // source
(val) => { // fetchData
return fetchData(val);
}
);
const params = useParams();
const [post] = createResource(
() => params.updatingVal, // source
(val) => { // fetchData
return fetchData(val);
}
);
Basically source (first arg of createResource) should be a function returning the value that's changing. If solid detects that that value changed, it will run the fetchData fetcher function passed to it as the second arg and will also pass to it the up-to-date value of the source as an argument. What I was doing wrong was passing a straight up value to the source arg.
Want results from more Discord servers?
Add your server