S
SolidJS•13mo ago
Merlin

Resource refetch doesn't trigger effect

I have this effect in my root layout (solid-start)
const user = useUser();
createEffect(() => {
console.log(user.name, user.email);
if (user.name) Crisp.user.setNickname(user.name);
if (user.email) Crisp.user.setEmail(user.email);
});
const user = useUser();
createEffect(() => {
console.log(user.name, user.email);
if (user.name) Crisp.user.setNickname(user.name);
if (user.email) Crisp.user.setEmail(user.email);
});
useUser:
function useUser() {
const [user, { mutate, refetch }] = createResource(() =>
api
.get<{
id: string;
role: "GUEST" | "USER";
email: string | null;
name: string | null;
teamId: string | null;
}>("/user/me")
.then((r) => r.data)
);

return {
refetch,
get email() {
return user()?.email;
},
get name() {
return user()?.name;
},
};
}
function useUser() {
const [user, { mutate, refetch }] = createResource(() =>
api
.get<{
id: string;
role: "GUEST" | "USER";
email: string | null;
name: string | null;
teamId: string | null;
}>("/user/me")
.then((r) => r.data)
);

return {
refetch,
get email() {
return user()?.email;
},
get name() {
return user()?.name;
},
};
}
When I call that refetch function from another component, I'd expect the effect in the 1st snippet to get re-run. Am I doing anything wrong?
11 Replies
Alex Lohr
Alex Lohr•13mo ago
any console messages?
foolswisdom
foolswisdom•13mo ago
You're only calling useUser once, right? (otherwise, you have two different resources, one from each call)
Alex Lohr
Alex Lohr•13mo ago
If you want to call it twice, you could use my resource package to cache the request: https://primitives.solidjs.community/package/resource#makecache
Solid Primitives
A library of high-quality primitives that extend SolidJS reactivity
Merlin
Merlin•13mo ago
Oh wow, no, I'm calling it twice 🤦 Thank you so much That's like a mini react-query, no? That's awesome Thank you :D
Alex Lohr
Alex Lohr•13mo ago
I hope it helps you. Yes, it's like the Lego bricks mini version of some of TanStack query's features. I find that I rarely need the full power of TanStack, so I created this primitive package. We have a lot of such helpful packages in solid-primitives and are always happy about content users and feature requests.
Merlin
Merlin•13mo ago
For anyone coming across this thread, this is how I use it:
type User = { name: string | null; email: string | null; }

export default function useUser() {
const [fetcher, invalidate] = makeCache(() =>
api.get<User>("/user/me").then((r) => r.data)
);

const [user, { refetch }] = createResource(fetcher);

// you don't have to do this -- returning `user` is fine. I return an obj with getters so I can use it like this:
// const user = useUser();
// user.email (instead of `user()?.email`)
return {
refetch() {
invalidate(); // invalidate response before refetching
return refetch();
},
get email() {
return user()?.email;
},
get name() {
return user()?.name;
},
};
}
type User = { name: string | null; email: string | null; }

export default function useUser() {
const [fetcher, invalidate] = makeCache(() =>
api.get<User>("/user/me").then((r) => r.data)
);

const [user, { refetch }] = createResource(fetcher);

// you don't have to do this -- returning `user` is fine. I return an obj with getters so I can use it like this:
// const user = useUser();
// user.email (instead of `user()?.email`)
return {
refetch() {
invalidate(); // invalidate response before refetching
return refetch();
},
get email() {
return user()?.email;
},
get name() {
return user()?.name;
},
};
}
@lexlohr is the "invalidate response before refetching" part required? or will calling refetch automatically invalidate, somehow?
Alex Lohr
Alex Lohr•13mo ago
No, at the moment, there is no such automatism. The question would be why you don't make this a global store resource?
Alex Lohr
Alex Lohr•13mo ago
You can just export it and enjoy fine-grained reactivity. Or for even more performance, you could use https://solid-primitives.netlify.app/package/static-store for the storage option of createResource.
Solid Primitives
A library of high-quality primitives that extend SolidJS reactivity
Alex Lohr
Alex Lohr•13mo ago
Maybe I should add something convenient to the resource package to use that directly.
Merlin
Merlin•13mo ago
That doesn't work with solid-start SSR unfortunately
Alex Lohr
Alex Lohr•13mo ago
Ah, you'd need to wrap this in onmount then.