S
SolidJS3mo ago
Eve

Why does this loop infinitely

The following code calls serverFunc endlessly
export default function Test() {
const [people, setPeople] = createStore([
{ id: '19' },
{ id: '11' },
]);

const serverFunc = async (id: string): Promise<string> => {
'use server';
console.log('running serverFunc');
return 'Not Found';
};

return (
<For each={people}>
{(person, index) => {
return (
<div>
{index() + 1}: {person.id}
<span>{createAsync(() => serverFunc(person.id))()}</span>
</div>
);
}}
</For>
);
}
export default function Test() {
const [people, setPeople] = createStore([
{ id: '19' },
{ id: '11' },
]);

const serverFunc = async (id: string): Promise<string> => {
'use server';
console.log('running serverFunc');
return 'Not Found';
};

return (
<For each={people}>
{(person, index) => {
return (
<div>
{index() + 1}: {person.id}
<span>{createAsync(() => serverFunc(person.id))()}</span>
</div>
);
}}
</For>
);
}
But if I change it to
<For each={people}>
{(person, index) => {
const response = createAsync(() => serverFunc(person.id));
return (
<div>
{index() + 1}: {person.id}
<span>{response()}</span>
</div>
);
}}
</For>
<For each={people}>
{(person, index) => {
const response = createAsync(() => serverFunc(person.id));
return (
<div>
{index() + 1}: {person.id}
<span>{response()}</span>
</div>
);
}}
</For>
it no longer loops. The two should be functionally identical. So why does the IIFE cause an infinite loop?
5 Replies
mdynnl
mdynnl3mo ago
The two should be functionally identical
no expressions in jsx are compiled to be wrapped with effect whereas the function passed to For as children is executed with untrack (same as a component's body)
Madaxen86
Madaxen863mo ago
createAsync is a primitive which you should not use in a reactive context like the JSX or inside effects. As mdynnl noted that inside the for callback the code outside the return is also untracked and therefore not reactive. That’s where you initialise the primitives and then use the returned value. The reason is that the primitive is recreated when the JSX updates so it and it updates the JSX, so essentially recreataes itself over and over.
Moritz
Moritz2mo ago
I'm having the same problem with nested cache. When triggering an action, both caches get revalidated somehow and triggering an infinite loop. Is it the same problem or something different?
Madaxen86
Madaxen862mo ago
Tough to make a solid statement without seeing the code. By default action revalidate the whole cache and this doesn’t create infinite loops. Keep your createAsync outside of reactive contexts (jsx,createEffect,createMemo) and you will be fine.
Moritz
Moritz2mo ago
Thanks for the understanding with server components and reactivity. This info was really useful ❤️
Want results from more Discord servers?
Add your server