Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/useAsObservable.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {BehaviorSubject, Observable} from 'rxjs'
import {useCallback, useRef} from 'react'
import {useIsomorphicEffect} from './useIsomorphicEffect'
import {useCallback, useEffect, useRef} from 'react'
import {distinctUntilChanged} from 'rxjs/operators'

/**
Expand Down Expand Up @@ -33,19 +32,30 @@ export function useAsObservable<T, K = T>(

const [observable] = ref.current

useIsomorphicEffect(() => {
useEffect(() => {
if (!ref.current) {
return
}
const [, subject] = ref.current
subject.next(value)
}, [value, ref])

useIsomorphicEffect(() => {
const shouldRestoreSubscriptionRef = useRef(false)
useEffect(() => {
if (shouldRestoreSubscriptionRef.current) {
if (!ref.current) {
ref.current = setup()
}
shouldRestoreSubscriptionRef.current = false
}

return () => {
if (!ref.current) {
return
}
// React StrictMode will call effects as `setup + teardown + setup` thus we can't trust this callback as "react is about to unmount"
// Tracking this ref lets us set the subscription back up on the next `setup` call if needed, and if it really did unmounted then all is well
shouldRestoreSubscriptionRef.current = true
const [, subject] = ref.current
subject.complete()
ref.current = undefined
Expand Down
3 changes: 3 additions & 0 deletions src/useObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ export function useObservable<T>(observable: Observable<T>, initialValue?: T | (
[() => T, Parameters<typeof useSyncExternalStore>[0]]
>(() => {
const store = getOrCreateStore(observable, getValue(initialValue))
if (store.subscription.closed) {
store.subscription = store.observable.subscribe()
}
Comment on lines +41 to +43
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a temporary brute force fix for sanity studio, I'll revisit after testing it properly. Worst case it never runs.

return [
function getSnapshot() {
// @TODO: perf opt opportunity: we could do `store.subscription.unsubscribe()` here to clear up some memory, as this subscription is only needed to provide a sync initialValue.
Expand Down