-
Notifications
You must be signed in to change notification settings - Fork 20
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
Add getServerSnapshot, fix loop on SSR Subscribe #306
Conversation
Codecov Report
@@ Coverage Diff @@
## main #306 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 24 25 +1
Lines 1232 1279 +47
Branches 141 148 +7
=========================================
+ Hits 1232 1279 +47
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
args: [, gv] as any, | ||
args: [, gv, gv] as any, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can use gv
for serverSnapshot because everything still matches:
const gv: <T>() => Exclude<T, typeof SUSPENSE> = () => {
const src = callbackRef.current!.source$ as DefaultedStateObservable<O>
if (!src.getRefCount() && !src.getDefaultValue) {
// `subscription` will always be null, because it's impossible for a component to run this hook if it's inside a <Subscribe>
// Then this will happen only if a component without a <Subscribe> is using a StateObservable that doesn't have a subscription => Missing Subscribe
if (!subscription) throw new Error("Missing Subscribe!")
subscription(src)
}
// The rest should also work:
// Observables with top-level subscriptions will return their value, or trigger Suspense
// Observables without subscriptions and defaultValue will return their defaultValue
return getValue(src)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Thanks a lot @voliva !
Does this means one should not use this in server side components? |
At the moment I don't really have an answer for this, I haven't played that much with SSR or server-side components. It's just important to keep in mind that in server-side:
My best advice (again, without having played that much with SSR/NextJS) is to have every StateObservable with a defaultValue on those components that will run on the Server. It gives the most predictable and simple results: They will return the defaultValue while on the server, and execute the subscription when on the client. Maybe on a future we can leverage something like reactjs/rfcs#229 so that server components also subscribe to the observables, but there are some serious questions regarding cancellation and state sharing. |
Fixes #305
Something important to keep in mind is that in SSR any children within a
Subscribe
will not render, because given that components never mount in SSR (including<Subscribe>
), it will never get into the stage of rendering the children.And
StateObservable
with top-level subscriptions will have their state shared between clients.