rxjs-hooks
Advanced tools
Comparing version 0.7.0 to 0.8.0-alpha.0
@@ -8,17 +8,23 @@ "use strict"; | ||
var rxjs_1 = require("rxjs"); | ||
var operators_1 = require("rxjs/operators"); | ||
var shim_1 = require("use-sync-external-store/shim"); | ||
function useEventCallback(callback, initialState, inputs) { | ||
var initialValue = (typeof initialState !== 'undefined' ? initialState : null); | ||
var _a = tslib_1.__read(react_1.useState(initialValue), 2), state = _a[0], setState = _a[1]; | ||
var event$ = use_constant_1.default(function () { return new rxjs_1.Subject(); }); | ||
var state$ = use_constant_1.default(function () { return new rxjs_1.BehaviorSubject(initialValue); }); | ||
var inputs$ = use_constant_1.default(function () { return new rxjs_1.BehaviorSubject(typeof inputs === 'undefined' ? null : inputs); }); | ||
function eventCallback(e) { | ||
return event$.next(e); | ||
} | ||
var returnedCallback = react_1.useCallback(eventCallback, []); | ||
react_1.useEffect(function () { | ||
var event$ = (0, use_constant_1.default)(function () { return new rxjs_1.Subject(); }); | ||
var state$ = (0, use_constant_1.default)(function () { return new rxjs_1.BehaviorSubject(initialValue); }); | ||
var inputs$ = (0, use_constant_1.default)(function () { return new rxjs_1.BehaviorSubject(typeof inputs === 'undefined' ? null : inputs); }); | ||
(0, react_1.useEffect)(function () { | ||
return function () { | ||
state$.complete(); | ||
inputs$.complete(); | ||
event$.complete(); | ||
}; | ||
}, []); | ||
var returnedCallback = (0, react_1.useCallback)(function eventCallback(e) { | ||
event$.next(e); | ||
}, []); | ||
(0, react_1.useEffect)(function () { | ||
inputs$.next(inputs); | ||
}, inputs || []); | ||
react_1.useEffect(function () { | ||
setState(initialValue); | ||
var subscribe = (0, react_1.useMemo)(function () { | ||
var value$; | ||
@@ -31,13 +37,11 @@ if (!inputs) { | ||
} | ||
var subscription = value$.subscribe(function (value) { | ||
state$.next(value); | ||
setState(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
state$.complete(); | ||
inputs$.complete(); | ||
event$.complete(); | ||
return function (onStorageChange) { | ||
var subscription = value$.pipe((0, operators_1.tap)(function (s) { return state$.next(s); })).subscribe(onStorageChange); | ||
return function () { return subscription.unsubscribe(); }; | ||
}; | ||
}, []); // immutable forever | ||
}, []); | ||
var getSnapShot = (0, react_1.useMemo)(function () { | ||
return function () { return state$.getValue(); }; | ||
}, []); | ||
var state = (0, shim_1.useSyncExternalStore)(subscribe, getSnapShot, getSnapShot); | ||
return [returnedCallback, state]; | ||
@@ -44,0 +48,0 @@ } |
@@ -6,12 +6,19 @@ "use strict"; | ||
var rxjs_1 = require("rxjs"); | ||
var operators_1 = require("rxjs/operators"); | ||
var react_1 = require("react"); | ||
var use_constant_1 = tslib_1.__importDefault(require("use-constant")); | ||
var shim_1 = require("use-sync-external-store/shim"); | ||
function useObservable(inputFactory, initialState, inputs) { | ||
var _a = tslib_1.__read(react_1.useState(typeof initialState !== 'undefined' ? initialState : null), 2), state = _a[0], setState = _a[1]; | ||
var state$ = use_constant_1.default(function () { return new rxjs_1.BehaviorSubject(initialState); }); | ||
var inputs$ = use_constant_1.default(function () { return new rxjs_1.BehaviorSubject(inputs); }); | ||
react_1.useEffect(function () { | ||
var state$ = (0, use_constant_1.default)(function () { return new rxjs_1.BehaviorSubject(initialState); }); | ||
var inputs$ = (0, use_constant_1.default)(function () { return new rxjs_1.BehaviorSubject(inputs); }); | ||
(0, react_1.useEffect)(function () { | ||
return function () { | ||
state$.complete(); | ||
inputs$.complete(); | ||
}; | ||
}, []); | ||
(0, react_1.useEffect)(function () { | ||
inputs$.next(inputs); | ||
}, inputs || []); | ||
react_1.useEffect(function () { | ||
var subscribe = (0, react_1.useMemo)(function () { | ||
var output$; | ||
@@ -24,15 +31,13 @@ if (inputs) { | ||
} | ||
var subscription = output$.subscribe(function (value) { | ||
state$.next(value); | ||
setState(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
inputs$.complete(); | ||
state$.complete(); | ||
return function (onStorageChange) { | ||
var subscription = output$.pipe((0, operators_1.tap)(function (s) { return state$.next(s); })).subscribe(onStorageChange); | ||
return function () { return subscription.unsubscribe(); }; | ||
}; | ||
}, []); // immutable forever | ||
return state; | ||
}, []); | ||
var getSnapShot = (0, react_1.useMemo)(function () { | ||
return function () { var _a; return (_a = state$.getValue()) !== null && _a !== void 0 ? _a : null; }; | ||
}, []); | ||
return (0, shim_1.useSyncExternalStore)(subscribe, getSnapShot, getSnapShot); | ||
} | ||
exports.useObservable = useObservable; | ||
//# sourceMappingURL=use-observable.js.map |
@@ -1,20 +0,25 @@ | ||
import { __read } from "tslib"; | ||
import { useEffect, useState, useCallback } from 'react'; | ||
import { useEffect, useCallback, useMemo } from 'react'; | ||
import useConstant from 'use-constant'; | ||
import { BehaviorSubject, Subject } from 'rxjs'; | ||
import { tap } from 'rxjs/operators'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim'; | ||
export function useEventCallback(callback, initialState, inputs) { | ||
var initialValue = (typeof initialState !== 'undefined' ? initialState : null); | ||
var _a = __read(useState(initialValue), 2), state = _a[0], setState = _a[1]; | ||
var event$ = useConstant(function () { return new Subject(); }); | ||
var state$ = useConstant(function () { return new BehaviorSubject(initialValue); }); | ||
var inputs$ = useConstant(function () { return new BehaviorSubject(typeof inputs === 'undefined' ? null : inputs); }); | ||
function eventCallback(e) { | ||
return event$.next(e); | ||
} | ||
var returnedCallback = useCallback(eventCallback, []); | ||
useEffect(function () { | ||
return function () { | ||
state$.complete(); | ||
inputs$.complete(); | ||
event$.complete(); | ||
}; | ||
}, []); | ||
var returnedCallback = useCallback(function eventCallback(e) { | ||
event$.next(e); | ||
}, []); | ||
useEffect(function () { | ||
inputs$.next(inputs); | ||
}, inputs || []); | ||
useEffect(function () { | ||
setState(initialValue); | ||
var subscribe = useMemo(function () { | ||
var value$; | ||
@@ -27,15 +32,13 @@ if (!inputs) { | ||
} | ||
var subscription = value$.subscribe(function (value) { | ||
state$.next(value); | ||
setState(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
state$.complete(); | ||
inputs$.complete(); | ||
event$.complete(); | ||
return function (onStorageChange) { | ||
var subscription = value$.pipe(tap(function (s) { return state$.next(s); })).subscribe(onStorageChange); | ||
return function () { return subscription.unsubscribe(); }; | ||
}; | ||
}, []); // immutable forever | ||
}, []); | ||
var getSnapShot = useMemo(function () { | ||
return function () { return state$.getValue(); }; | ||
}, []); | ||
var state = useSyncExternalStore(subscribe, getSnapShot, getSnapShot); | ||
return [returnedCallback, state]; | ||
} | ||
//# sourceMappingURL=use-event-callback.js.map |
@@ -1,13 +0,19 @@ | ||
import { __read } from "tslib"; | ||
import { BehaviorSubject } from 'rxjs'; | ||
import { useState, useEffect } from 'react'; | ||
import { tap } from 'rxjs/operators'; | ||
import { useEffect, useMemo } from 'react'; | ||
import useConstant from 'use-constant'; | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim'; | ||
export function useObservable(inputFactory, initialState, inputs) { | ||
var _a = __read(useState(typeof initialState !== 'undefined' ? initialState : null), 2), state = _a[0], setState = _a[1]; | ||
var state$ = useConstant(function () { return new BehaviorSubject(initialState); }); | ||
var inputs$ = useConstant(function () { return new BehaviorSubject(inputs); }); | ||
useEffect(function () { | ||
return function () { | ||
state$.complete(); | ||
inputs$.complete(); | ||
}; | ||
}, []); | ||
useEffect(function () { | ||
inputs$.next(inputs); | ||
}, inputs || []); | ||
useEffect(function () { | ||
var subscribe = useMemo(function () { | ||
var output$; | ||
@@ -20,14 +26,12 @@ if (inputs) { | ||
} | ||
var subscription = output$.subscribe(function (value) { | ||
state$.next(value); | ||
setState(value); | ||
}); | ||
return function () { | ||
subscription.unsubscribe(); | ||
inputs$.complete(); | ||
state$.complete(); | ||
return function (onStorageChange) { | ||
var subscription = output$.pipe(tap(function (s) { return state$.next(s); })).subscribe(onStorageChange); | ||
return function () { return subscription.unsubscribe(); }; | ||
}; | ||
}, []); // immutable forever | ||
return state; | ||
}, []); | ||
var getSnapShot = useMemo(function () { | ||
return function () { var _a; return (_a = state$.getValue()) !== null && _a !== void 0 ? _a : null; }; | ||
}, []); | ||
return useSyncExternalStore(subscribe, getSnapShot, getSnapShot); | ||
} | ||
//# sourceMappingURL=use-observable.js.map |
{ | ||
"name": "rxjs-hooks", | ||
"version": "0.7.0", | ||
"version": "0.8.0-alpha.0", | ||
"description": "React hooks for RxJS", | ||
@@ -15,3 +15,3 @@ "module": "dist/esm/index.js", | ||
"build:cjs": "rm -rf dist/cjs && tsc -p src/tsconfig.json --module commonjs --target es5 --outDir dist/cjs", | ||
"start": "webpack-dev-server --config ./tools/webpack.config.js --progress --color", | ||
"start": "vite", | ||
"test": "NODE_ENV=test jest --no-cache --ci", | ||
@@ -28,11 +28,13 @@ "lint": "yarn lint:eslint && yarn lint:tsc", | ||
"devDependencies": { | ||
"@types/jest": "^26.0.0", | ||
"@types/jest": "^27.0.1", | ||
"@types/lodash": "^4.14.149", | ||
"@types/react-dom": "^17.0.0", | ||
"@types/react-test-renderer": "^17.0.0", | ||
"@types/sinon": "^9.0.0", | ||
"@types/react": "^18.0.12", | ||
"@types/react-dom": "^18.0.0", | ||
"@types/react-test-renderer": "^18.0.0", | ||
"@types/sinon": "^10.0.0", | ||
"@types/sinon-chai": "^3.2.3", | ||
"@types/webpack": "^4.41.0", | ||
"@types/use-sync-external-store": "^0.0.3", | ||
"@typescript-eslint/eslint-plugin": "^4.19.0", | ||
"@typescript-eslint/parser": "^4.19.0", | ||
"@vitejs/plugin-react": "^1.3.2", | ||
"browser-resolve": "^2.0.0", | ||
@@ -43,30 +45,25 @@ "codecov": "^3.6.1", | ||
"eslint-plugin-react": "^7.23.1", | ||
"fork-ts-checker-webpack-plugin": "^6.0.0", | ||
"happypack": "^5.0.1", | ||
"html-webpack-plugin": "^5.0.0", | ||
"husky": "^5.2.0", | ||
"jest": "^26.0.1", | ||
"lint-staged": "^10.0.1", | ||
"husky": "^8.0.1", | ||
"jest": "^27.0.4", | ||
"lint-staged": "^13.0.0", | ||
"prettier": "^2.0.1", | ||
"react": "17.0.1", | ||
"react-dom": "17.0.1", | ||
"react-test-renderer": "17.0.1", | ||
"rxjs": "^6.5.3", | ||
"sinon": "^9.0.0", | ||
"source-map-loader": "^2.0.0", | ||
"standard": "^16.0.0", | ||
"ts-jest": "^26.0.0", | ||
"ts-loader": "^8.0.0", | ||
"react": "18.1.0", | ||
"react-dom": "18.1.0", | ||
"react-test-renderer": "18.1.0", | ||
"rxjs": "^7.0.0", | ||
"sinon": "^14.0.0", | ||
"standard": "^17.0.0", | ||
"ts-jest": "^27.0.2", | ||
"typescript": "^4.2.0", | ||
"webpack": "^5.0.0", | ||
"webpack-cli": "^4.0.0", | ||
"webpack-dev-server": "^3.9.0" | ||
"vite": "^2.9.12" | ||
}, | ||
"dependencies": { | ||
"tslib": "^2.1.0", | ||
"use-constant": "^1.0.0" | ||
"use-constant": "^1.0.0", | ||
"use-sync-external-store": "^1.1.0" | ||
}, | ||
"peerDependencies": { | ||
"react": "17.0.1", | ||
"rxjs": "^6.5.3" | ||
"react": ">=16.8.0", | ||
"rxjs": ">=7.0.0" | ||
}, | ||
@@ -73,0 +70,0 @@ "lint-staged": { |
@@ -290,3 +290,3 @@ # React hooks for RxJS | ||
**A complex example: useEventCallback with both inputs$ and state$** | ||
**A complex example: useEventCallback with both `inputs$` and `state$`** | ||
@@ -400,1 +400,4 @@ [live demo](https://codesandbox.io/s/n1pn02jxym) | ||
``` | ||
## Known issues | ||
If you are using React 18 + `StrictMode`, `rxjs-hooks` will not work properly. Because in React 18, `StrictMode` will force unmount hooks to trigger twice, which will result in unexpected behaviours. |
@@ -1,4 +0,6 @@ | ||
import { useEffect, useState, useCallback } from 'react' | ||
import { useEffect, useCallback, useMemo } from 'react' | ||
import useConstant from 'use-constant' | ||
import { Observable, BehaviorSubject, Subject } from 'rxjs' | ||
import { tap } from 'rxjs/operators' | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim' | ||
@@ -47,3 +49,2 @@ import { RestrictArray, VoidAsNull, Not } from './type' | ||
const initialValue = (typeof initialState !== 'undefined' ? initialState : null) as VoidAsNull<State> | ||
const [state, setState] = useState(initialValue) | ||
const event$ = useConstant(() => new Subject<EventValue>()) | ||
@@ -55,7 +56,14 @@ const state$ = useConstant(() => new BehaviorSubject<State | null>(initialValue)) | ||
function eventCallback(e: EventValue) { | ||
return event$.next(e) | ||
} | ||
const returnedCallback = useCallback(eventCallback, []) | ||
useEffect(() => { | ||
return () => { | ||
state$.complete() | ||
inputs$.complete() | ||
event$.complete() | ||
} | ||
}, []) | ||
const returnedCallback = useCallback(function eventCallback(e: EventValue) { | ||
event$.next(e) | ||
}, []) | ||
useEffect(() => { | ||
@@ -65,6 +73,4 @@ inputs$.next(inputs!) | ||
useEffect(() => { | ||
setState(initialValue) | ||
const subscribe = useMemo(() => { | ||
let value$: Observable<State> | ||
if (!inputs) { | ||
@@ -75,15 +81,15 @@ value$ = (callback as EventCallback<EventValue, State, void>)(event$, state$ as Observable<State>) | ||
} | ||
const subscription = value$.subscribe((value) => { | ||
state$.next(value) | ||
setState(value as VoidAsNull<State>) | ||
}) | ||
return () => { | ||
subscription.unsubscribe() | ||
state$.complete() | ||
inputs$.complete() | ||
event$.complete() | ||
return (onStorageChange: () => void) => { | ||
const subscription = value$.pipe(tap((s) => state$.next(s))).subscribe(onStorageChange) | ||
return () => subscription.unsubscribe() | ||
} | ||
}, []) // immutable forever | ||
}, []) | ||
const getSnapShot = useMemo(() => { | ||
return () => state$.getValue() as VoidAsNull<State> | ||
}, []) | ||
const state = useSyncExternalStore(subscribe, getSnapShot, getSnapShot) | ||
return [returnedCallback as VoidableEventCallback<EventValue>, state] | ||
} |
import { Observable, BehaviorSubject } from 'rxjs' | ||
import { useState, useEffect } from 'react' | ||
import { tap } from 'rxjs/operators' | ||
import { useEffect, useMemo } from 'react' | ||
import useConstant from 'use-constant' | ||
import { useSyncExternalStore } from 'use-sync-external-store/shim' | ||
@@ -25,4 +27,2 @@ import { RestrictArray } from './type' | ||
): State | null { | ||
const [state, setState] = useState(typeof initialState !== 'undefined' ? initialState : null) | ||
const state$ = useConstant(() => new BehaviorSubject<State | undefined>(initialState)) | ||
@@ -32,29 +32,35 @@ const inputs$ = useConstant(() => new BehaviorSubject<RestrictArray<Inputs> | undefined>(inputs)) | ||
useEffect(() => { | ||
return () => { | ||
state$.complete() | ||
inputs$.complete() | ||
} | ||
}, []) | ||
useEffect(() => { | ||
inputs$.next(inputs) | ||
}, inputs || []) | ||
useEffect(() => { | ||
let output$: BehaviorSubject<State> | ||
const subscribe = useMemo(() => { | ||
let output$: Observable<State> | ||
if (inputs) { | ||
output$ = (inputFactory as ( | ||
state$: Observable<State | undefined>, | ||
inputs$: Observable<RestrictArray<Inputs> | undefined>, | ||
) => Observable<State>)(state$, inputs$) as BehaviorSubject<State> | ||
output$ = ( | ||
inputFactory as ( | ||
state$: Observable<State | undefined>, | ||
inputs$: Observable<RestrictArray<Inputs> | undefined>, | ||
) => Observable<State> | ||
)(state$, inputs$) | ||
} else { | ||
output$ = ((inputFactory as unknown) as (state$: Observable<State | undefined>) => Observable<State>)( | ||
state$, | ||
) as BehaviorSubject<State> | ||
output$ = (inputFactory as unknown as (state$: Observable<State | undefined>) => Observable<State>)(state$) | ||
} | ||
const subscription = output$.subscribe((value) => { | ||
state$.next(value) | ||
setState(value) | ||
}) | ||
return () => { | ||
subscription.unsubscribe() | ||
inputs$.complete() | ||
state$.complete() | ||
return (onStorageChange: () => void) => { | ||
const subscription = output$.pipe(tap((s) => state$.next(s))).subscribe(onStorageChange) | ||
return () => subscription.unsubscribe() | ||
} | ||
}, []) // immutable forever | ||
}, []) | ||
return state | ||
const getSnapShot = useMemo(() => { | ||
return () => state$.getValue() ?? null | ||
}, []) | ||
return useSyncExternalStore(subscribe, getSnapShot, getSnapShot) | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40234
30
36
454
402
5
+ Addedreact@18.3.119.0.0(transitive)
+ Addedrxjs@7.8.1(transitive)
+ Addeduse-sync-external-store@1.4.0(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedreact@17.0.1(transitive)
- Removedrxjs@6.6.7(transitive)
- Removedtslib@1.14.1(transitive)