fix(core): ensure that all subscriptions count for the refcount

This commit is contained in:
Josep M Sobrepere 2021-03-02 11:48:01 +01:00
parent b9ee430590
commit e37245006f
8 changed files with 68 additions and 21 deletions

View File

@ -1,5 +1,5 @@
{
"version": "0.6.5",
"version": "0.6.6",
"repository": {
"type": "git",
"url": "git+https://github.com/re-rxjs/react-rxjs.git"

View File

@ -1,4 +1,4 @@
import React, { useState, Suspense, useLayoutEffect, ReactNode } from "react"
import React, { useState, Suspense, useEffect, ReactNode } from "react"
import { Observable, noop } from "rxjs"
const p = Promise.resolve()
@ -38,7 +38,7 @@ export const Subscribe: React.FC<{
}
}
useLayoutEffect(() => {
useEffect(() => {
const subscription = source$.subscribe(noop, (e) =>
setSubscribedSource(() => {
throw e

View File

@ -19,6 +19,7 @@ import {
switchMapTo,
first,
startWith,
switchMap,
} from "rxjs/operators"
import { FC, useState } from "react"
import React from "react"
@ -28,6 +29,7 @@ import {
screen,
render,
act,
waitFor,
} from "@testing-library/react"
import { bind, Subscribe } from "../"
import { TestErrorBoundary } from "../test-helpers/TestErrorBoundary"
@ -610,6 +612,66 @@ describe("connectFactoryObservable", () => {
expect(value).toBe(5)
})
it("ensures that components subscriptions are being taken into account", async () => {
const ticks$ = new Subject<void>()
const [useValue, getValue$] = bind((_: string) =>
ticks$.pipe(map((_, idx) => idx)),
)
const update$ = new Subject<void>()
const key = "foo"
const subscription$ = update$.pipe(
startWith(""),
switchMap(() => getValue$(key)),
)
const Result: React.FC = () => <div>Result {useValue(key)}</div>
const Container: React.FC = () => {
return (
<>
<Subscribe source$={subscription$} fallback={<span>Waiting</span>}>
<Result />
</Subscribe>
<button onClick={() => update$.next()}>Next</button>
</>
)
}
render(<Container />)
expect(screen.queryByText("Waiting")).not.toBeNull()
componentAct(() => {
ticks$.next()
})
await waitFor(() => expect(screen.queryByText("Waiting")).toBeNull())
expect(screen.getByText("Result 0")).not.toBeNull()
componentAct(() => {
ticks$.next()
})
await waitFor(() => expect(screen.getByText("Result 1")).not.toBeNull())
componentAct(() => {
ticks$.next()
})
await waitFor(() => expect(screen.getByText("Result 2")).not.toBeNull())
componentAct(() => {
fireEvent.click(screen.getByText(/Next/i))
})
expect(screen.getByText("Result 2")).not.toBeNull()
componentAct(() => {
ticks$.next()
})
await waitFor(() => expect(screen.getByText("Result 3")).not.toBeNull())
})
describe("observable", () => {
it("it does not complete when the source observable completes", async () => {
let diff = -1

View File

@ -61,13 +61,11 @@ export default function connectFactoryObservable<A extends [], O>(
} else if (inCache !== publicShared$) {
source$ = inCache
publicShared$.gV = source$.gV
publicShared$.aH = source$.aH
}
return source$.subscribe(subscriber)
}) as BehaviorObservable<O>
publicShared$.gV = sharedObservable$.gV
publicShared$.aH = sharedObservable$.aH
const result: BehaviorObservable<O> = publicShared$

View File

@ -74,19 +74,6 @@ const shareLatest = <T>(
}
}) as BehaviorObservable<T>
result.aH = (n: any, e: any) => {
let subscription
if (defaultValue === EMPTY_VALUE) {
subscription = subject!.subscribe(n, e)
if (currentValue !== EMPTY_VALUE) {
n(currentValue)
}
} else {
subscription = result.subscribe(n, e)
}
return subscription
}
let error: any = EMPTY_VALUE
let timeoutToken: any
result.gV = (): T => {

View File

@ -21,7 +21,7 @@ export const useObservable = <O>(
}
let isEmpty = true
const subscription = source$.aH(
const subscription = source$.subscribe(
(value: O | typeof SUSPENSE) => {
isEmpty = false
if (value === SUSPENSE) {

View File

@ -40,7 +40,7 @@
"Victor Oliva (https://github.com/voliva)"
],
"devDependencies": {
"@react-rxjs/core": "0.6.5",
"@react-rxjs/core": "0.6.6",
"@testing-library/react": "^11.2.3",
"@testing-library/react-hooks": "^3.4.2",
"@types/jest": "^26.0.20",

View File

@ -40,7 +40,7 @@
"Victor Oliva (https://github.com/voliva)"
],
"devDependencies": {
"@react-rxjs/core": "0.6.5",
"@react-rxjs/core": "0.6.6",
"@testing-library/react": "^11.2.3",
"@testing-library/react-hooks": "^3.4.2",
"@types/jest": "^26.0.20",