useSyncExternalStore

This commit is contained in:
Josep M Sobrepere 2022-03-07 17:10:16 +01:00
parent 0146db604f
commit da0dcbfcdd
No known key found for this signature in database
GPG Key ID: 9A207FDA2481C91A
5 changed files with 49 additions and 47 deletions

View File

@ -48,5 +48,11 @@
"authors": [
"Josep M Sobrepere (https://github.com/josepot)",
"Victor Oliva (https://github.com/voliva)"
]
],
"dependencies": {
"use-sync-external-store": "^1.0.0-rc.0"
},
"devDependencies": {
"@types/use-sync-external-store": "^0.0.3"
}
}

View File

@ -2,5 +2,4 @@ import { Observable, Subscription } from "rxjs"
export interface BehaviorObservable<T> extends Observable<T> {
gV: (subscription?: Subscription) => T
aH: any
}

View File

@ -74,22 +74,10 @@ const shareLatest = <T>(
}
}) as BehaviorObservable<T>
let error: any = EMPTY_VALUE
let timeoutToken: any
result.gV = (outterSubscription?: Subscription): T => {
if (currentValue !== EMPTY_VALUE) {
return currentValue
}
if (currentValue !== EMPTY_VALUE) return currentValue
if (defaultValue !== EMPTY_VALUE) return defaultValue
if (error !== EMPTY_VALUE) {
clearTimeout(timeoutToken)
timeoutToken = setTimeout(() => {
error = EMPTY_VALUE
}, 50)
throw error
}
if (!subscription) {
if (!outterSubscription) throw new Error("Missing Subscribe")
@ -108,10 +96,6 @@ const shareLatest = <T>(
throw (promise = new Promise<T>((res, rej) => {
const setError = (e: any) => {
error = e
timeoutToken = setTimeout(() => {
error = EMPTY_VALUE
}, 50)
rej(e)
promise = null
}

View File

@ -1,39 +1,42 @@
import { useEffect, useState, useRef } from "react"
import { useSyncExternalStore } from "use-sync-external-store/shim"
import { BehaviorObservable } from "../internal/BehaviorObservable"
import { Subscription } from "rxjs"
import { useRef, useState } from "react"
type VoidCb = () => void
interface Ref<T> {
args: [(cb: VoidCb) => VoidCb, () => T]
source$: BehaviorObservable<T>
}
export const useObservable = <O>(
source$: BehaviorObservable<O>,
subscription?: Subscription,
): O => {
const [state, setState] = useState<[O, BehaviorObservable<O>]>(() => [
source$.gV(subscription),
source$,
])
const prevStateRef = useRef<O | (() => O)>(state[0])
const [, setError] = useState()
const callbackRef = useRef<Ref<O>>()
if (source$ !== state[1]) {
setState([source$.gV(subscription), source$])
if (!callbackRef.current || callbackRef.current.source$ !== source$) {
callbackRef.current = {
source$,
args: [
(next: () => void) => {
const subscription = source$.subscribe({
next,
error: (e) => {
setError(() => {
throw e
})
},
})
return () => subscription.unsubscribe()
},
() => source$.gV(subscription),
],
}
}
useEffect(() => {
const subscription = source$.subscribe({
next: (value: O) => {
if (!Object.is(prevStateRef.current, value)) {
setState([(prevStateRef.current = value), source$])
}
},
error: (error: any) => {
setState(() => {
throw error
})
},
})
return () => {
subscription.unsubscribe()
}
}, [source$])
return state[0]
return useSyncExternalStore(...callbackRef.current!.args)
}

View File

@ -1382,6 +1382,11 @@
dependencies:
"@types/jest" "*"
"@types/use-sync-external-store@^0.0.3":
version "0.0.3"
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
"@types/yargs-parser@*":
version "21.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b"
@ -4122,6 +4127,11 @@ universalify@^0.1.2:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
use-sync-external-store@^1.0.0-rc.0:
version "1.0.0-rc.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.0.0-rc.0.tgz#0d8fb7cbc31ddfb3ee01225f6b0a700cf59c449b"
integrity sha512-0U9Xlc2QDFzSGMB0DvcJQL0+DIdxDPJC7mnZlYFbl7wrSrPMcs89X5TVkNB6Dzg618m8lZop+U+J6ow3vq9RAQ==
v8-to-istanbul@^8.1.0:
version "8.1.1"
resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed"