Skip to content
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

SSR and react-rxjs #313

Open
Jesus-Gonzalez opened this issue Nov 25, 2023 · 1 comment
Open

SSR and react-rxjs #313

Jesus-Gonzalez opened this issue Nov 25, 2023 · 1 comment

Comments

@Jesus-Gonzalez
Copy link

Hello,

For now, the applications I've been working on with react-rxjs are SPA that are client side rendering only - no SSR is implemented.
Given the new trend on frontend application development with javascript - SSR is becoming the norm for every project.
I've also started working on a side-project that's going to implement SSR - although it's initially rendering client side only.

Are there any guide or best practices in order to implement SSR and using react-rxjs?

I'm thinking about possible issues arising - for example:

  • double requests to the BE API/server (when server renders and firstValueFrom an observable - and another when rendering client side)
  • maintaining and hydrating state on the state observables when first rendering
  • React rendering twice - when it first renders the generated SSR document - when the components mount.

Jesús

@voliva
Copy link
Collaborator

voliva commented Nov 25, 2023

This library was primarily designed for client-side-only SPAs, so its support for SSR is minimal. The components will render normally in SSR, but the app won't subscribe to any of the observables.

I have prepared a very small NextJS sandbox to demonstrate that it renders on server by using the default value, and for states without a default value it works fine with suspense as well: https://codesandbox.io/p/devbox/holy-framework-qplc5c?file=%2Fapp%2FCounter.tsx%3A30%2C2. To check it's actually being rendered in the server, you can access the result sandbox result directly on the URL https://qplc5c-3000.csb.app/ and look at the network tab. Keep in mind the SSR doesn't ever subscribe to any of the observables, it just gets the initial value or renders components as Suspended.

The primary reason for this limitation is that effects do not execute in SSR. You could externally manage the subscription of observables, and the components that use them will get their current value, but it's importat to note that the observables are shared for all the clients making requests. Which it's very limited in terms of what logic you can represent and use within the server.

On the last patch we did for SSR #306, I commented a few implications and some recommendations for this. But in a nutshell, avoid using top-level subscriptions, specify default values whenever possible, and keep in mind that anything inside a <Subscribe> will only be rendered in the client: This is because <Subscribe> only renders its children after it has subscribed to the source$, but it won't subscribe to the source$ when running in the server because effects don't run there.

Also I just checked and react-rxjs doesn't work at all with Server Components. I'm thinking this is expected, considering that hooks cannot even be used in Server Components, so there shouldn't be any need to import anything from react-rxjs.
You can import from @rx-state/core which has the state primitive without React's bindings (hooks + context + etc.) for building observables, but you still have to keep in mind any state those observables have will be shared among all clients performing requests, because they are defined in the global scope.

In summary, don't rely on react-rxjs to perform any observable logic when running on the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants