Defer creation of observable
OliverJAsh opened this issue · 2 comments
As I was migrating from useObservable
in rxjs-hooks to the one provided by this library, I ran into an interesting issue. Take this code:
useObservable(() => Rx.of(window.navigator.appName));
This code is part of a component which is rendered on the client and server. Of course, the observable will do nothing on the server, since it will never be subscribed to (effects are never ran in React SSR).
In rxjs-hooks this worked, but when I migrated it to this library I got an error on the server.
ReferenceError: window is not defined
IIUC, in rxjs-hooks the creation of the observable happens during an effect, immediately before subscription: https://github.com/LeetCode-OpenSource/rxjs-hooks/blob/89c4b89265b410a7c46cd5060629637e32c5ce8c/src/use-observable.ts#L37
Whereas in this library, the creation of the observable happens immediately during the render:
Perhaps we could wrap the init
call in defer
(from rxjs
)? Something like
- const source$Ref = useRefFn(() => init(inputs$Ref.current))
+ const source$Ref = useRefFn(() => defer(() => init(inputs$Ref.current)))
defer
creates a fresh observable for each observer which could be a breaking change for operators like share
.
Does this work?
useObservable(() => defer(() => Rx.of(window.navigator.appName)));
Or maybe add more hooks (or another lib) for dealing with server rendering stuff.
Good point, I'll do that for now!