-
-
Notifications
You must be signed in to change notification settings - Fork 878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Component doesn't reliably respond to a signal after hydration #2160
Comments
I see the issue it is just a bit tricky. The we are pretty lax when it comes to hydration in that we assume the server is correct and we don't correct text mismatches. If someone interacts with the page then we cancel hydration/streaming and apply the new state. However, if things are still hydrating we continue to assume the server is correct. What is happening in the example here is that since the one place is hydrating it assumes it doesn't need to do work but the signal under it has changed. So while the signal is being tracked and would update on another change it doesn't try to write the DOM initially. That being said in general lazy hydrating + shared state is just not a good idea. Because the client state can change and if it is shared hydration will break. Like consider a global counter that can be incremented and the lazy hydrated component shows/hides stuff based on whether the count is above 5. If anything changed the counter before it hydrated you'd have serious hydration errors. This error was less serious and wasn't detected, but it would cause hydration issues just the same in other solutions that were stricter. |
@ryansolid ahh, understood, thanks for that cogent explanation! Adding a If I can burden your generosity some more. Should I just abandon the hydration + shared state model? Is that just a Bad Idea™️? Or does one just have to be careful about this pitfall by making the signal-writer ( Edit: another terrible approach is to use an object as the signal's contents, and then in every hydrated reader component's // in signals.tsx
export const [user, setUser] = createSignal<{
user: string | undefined;
}>({ user: undefined }); // undefined = server-side
// in User.tsx, the signal writer component
export const User: Component = () => {
onMount(() => {
const savedUser = localStorage.getItem("user") ?? ""; // string = client-side
if (savedUser) setUser({ user: savedUser });
});
// ...
}
// in AvatarSolid.tsx, the signal reader component
export const AvatarSolid: Component = () => {
onMount(() => {
if (user().user !== undefined) setUser((x) => ({ ...x })); // cause a rerender if this component is hydrating late
});
// ...
} |
@fasiha Maybe instead of onMount you could use https://primitives.solidjs.community/package/lifecycle#ishydrated as a way to check if you are safe to change the signal 🤔 Edit: I guess function bootstrap(el: any, indirect: boolean, renderId: string) {
(indirect ? render : hydrate)(
() => (
<Suspense>
<Avatar indirect={indirect} />
</Suspense>
),
el,
{
renderId,
}
);
} |
Describe the bug
I have SSR enabled, and a module-scoped signal that is set
onMount
in one component. A second component that reads that signal doesn't reliably get notified when that signal is set.Your Example Website or App
https://stackblitz.com/edit/solidjs-templates-rqx1ev?file=vite.config.ts,src%2Findex.tsx,index.html,src%2FAvatar.tsx,src%2FUser.tsx
Steps to Reproduce the Bug or Issue
user
to "ahmed")Expected behavior
After refresh, I expect both bold lines to say
User is "ahmed"
(responding to theuser
signal being set by theUser
component'sonMount
)However, often one or both will say
User is ""
, not reacting to the signal. Sometimes this works, other times it doesn't.Screenshots or Videos
Platform
Additional context
Hypothesis from withastro/astro#11017:
The text was updated successfully, but these errors were encountered: