Skip to content

Commit

Permalink
feat(core/subscribe): change subscription state asap
Browse files Browse the repository at this point in the history
  • Loading branch information
voliva committed Nov 10, 2020
1 parent e251584 commit f6e2e0c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/Subscribe.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe("Subscribe", () => {
expect(nSubscriptions).toBe(0)
})

it("doesn't render its content until it has subscribed to a the source", () => {
it("doesn't render its content until it has subscribed to a new source", () => {
let nSubscriptions = 0
let errored = false
const [useInstance, instance$] = bind((id: number) => {
Expand Down
31 changes: 21 additions & 10 deletions packages/core/src/Subscribe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ const Throw = () => {
throw p
}

const initFn = (source$: Observable<any>) => {
try {
;(source$ as any).gV()
return source$
} catch (e) {
return e.then ? source$ : null
}
}

/**
* A React Component that creates a subscription to the provided observable once
* the component mounts and it unsubscribes when the component unmounts.
Expand All @@ -19,29 +28,31 @@ export const Subscribe: React.FC<{
source$: Observable<any>
fallback?: NonNullable<ReactNode> | null
}> = ({ source$, children, fallback }) => {
const [mounted, setMounted] = useState(() => {
try {
;(source$ as any).gV()
return source$
} catch (e) {
return e.then ? source$ : null
const [subscribedSource, setSubscribedSource] = useState(() =>
initFn(source$),
)
if (subscribedSource && subscribedSource !== source$) {
const result = initFn(source$)
if (result) {
setSubscribedSource(result)
}
})
}

useLayoutEffect(() => {
const subscription = source$.subscribe(noop, (e) =>
setMounted(() => {
setSubscribedSource(() => {
throw e
}),
)
setMounted(source$)
setSubscribedSource(source$)
return () => {
subscription.unsubscribe()
}
}, [source$])
const fBack = fallback || null
return (
<Suspense fallback={fBack}>
{mounted === source$ ? children : <Throw />}
{subscribedSource === source$ ? children : <Throw />}
</Suspense>
)
}
12 changes: 10 additions & 2 deletions packages/core/src/bind/connectFactoryObservable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ import {
merge,
} from "rxjs"
import { renderHook, act as actHook } from "@testing-library/react-hooks"
import { delay, take, catchError, map, switchMapTo } from "rxjs/operators"
import {
delay,
take,
catchError,
map,
switchMapTo,
first,
} from "rxjs/operators"
import { FC, useState } from "react"
import React from "react"
import {
Expand Down Expand Up @@ -242,7 +249,8 @@ describe("connectFactoryObservable", () => {
expect(screen.queryByText("Result")).toBeNull()
expect(screen.queryByText("Waiting")).not.toBeNull()
await componentAct(async () => {
await wait(60)
await getDelayedNumber$(0).pipe(first()).toPromise()
await wait(0)
})
expect(screen.queryByText("Result 0")).not.toBeNull()
expect(screen.queryByText("Waiting")).toBeNull()
Expand Down

0 comments on commit f6e2e0c

Please sign in to comment.