why store not updated in createAsync?

import { createStore } from "solid-js/store";
import { createAsync } from "solid-js";

export default function Demo() {
const [user, setUser] = createStore({ name: "Initial", age: 0 });

const data = createAsync(async () => {
console.log("Start async", user);

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", user);

await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", user);

return "done";
}, { deferStream: true });

return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
<h3>Data: {data()}</h3>
</div>
);
}
import { createStore } from "solid-js/store";
import { createAsync } from "solid-js";

export default function Demo() {
const [user, setUser] = createStore({ name: "Initial", age: 0 });

const data = createAsync(async () => {
console.log("Start async", user);

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", user);

await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", user);

return "done";
}, { deferStream: true });

return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
<h3>Data: {data()}</h3>
</div>
);
}
I update store in createAsync, but why it not updated in JSX?
3 Replies
brenelz
brenelz3d ago
I don't think createAsync can be used like that Just return your user from createAsync
PureSoul
PureSoulOP3d ago
but I want to know why it not work?
Madaxen86
Madaxen863d ago
As brenezl said: "never set state inside primivites (createEffect,createAsync,createSignal,createStore,...)". whenever you find yourself doing this: rethink your architecture. Usually the setter should be called in an event handler or check if you misunderstood how to use the docs. createAsync is executed on the server, setting the stores state at the server, however the store get recreated on the client during hydration with it's initial state. Just check your browser and cli (server) console logs. And there' aslo some race condition going on. when enabling break1 you'll get inital state, otherwise updated state.
const [user, setUser] = createStore({ name: "Initial", age: 0 });

const data = createAsync(
async () => {
console.log("Start async", user);
//break 1
await new Promise((r) => setTimeout(r, 2000));

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", unwrap(user));
//break 2
await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", unwrap(user));

return "done";
},
{ deferStream: true }
);
createEffect(() => console.log("user", unwrap(user)));
return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
<Suspense fallback="...async">
<h3>Data: {data()}</h3>
</Suspense>
</div>
);
const [user, setUser] = createStore({ name: "Initial", age: 0 });

const data = createAsync(
async () => {
console.log("Start async", user);
//break 1
await new Promise((r) => setTimeout(r, 2000));

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", unwrap(user));
//break 2
await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", unwrap(user));

return "done";
},
{ deferStream: true }
);
createEffect(() => console.log("user", unwrap(user)));
return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
<Suspense fallback="...async">
<h3>Data: {data()}</h3>
</Suspense>
</div>
);
What you could do instead - but again this looks like a anti pattern:
const [user, setUser] = createStore({ name: "Initial", age: 0 });

//const data = createAsync(
onMount(async () => {
console.log("Start async", user);
//break 1
await new Promise((r) => setTimeout(r, 2000));

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", unwrap(user));
//break 2
await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", unwrap(user));

return "done";
});

createEffect(() => console.log("user"));
return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
{/* <Suspense fallback="...async">
<h3>Data: {data()}</h3>
</Suspense> */}
</div>
);
const [user, setUser] = createStore({ name: "Initial", age: 0 });

//const data = createAsync(
onMount(async () => {
console.log("Start async", user);
//break 1
await new Promise((r) => setTimeout(r, 2000));

setUser({ name: "Changed", age: 99 });
console.log("After setUser, user:", unwrap(user));
//break 2
await new Promise((r) => setTimeout(r, 2000));

console.log("After 2s, user:", unwrap(user));

return "done";
});

createEffect(() => console.log("user"));
return (
<div>
<h1>User Name: {user.name}</h1> {/* ❓ */}
<h2>User Age: {user.age}</h2> {/* ❓ */}
{/* <Suspense fallback="...async">
<h3>Data: {data()}</h3>
</Suspense> */}
</div>
);
This will show the initial state and then set data after hydration on the client.

Did you find this page helpful?