Fetch data with React hooks and RxJS. Inspired by react-async
const state = useRxAsync(asyncFn, options?);
name | description |
---|---|
data | The value return from asyncFn |
loading | boolean |
error | any, depends on your asyncFn |
cancel | ignore the new value return from your asyncFn |
reset | reset data, loading, error to initialValue |
A function that return PromiseLike
or Observable
. For examples,
const delay = (ms: number) => new Promise(_ => setTimeout(_, ms));
const rxAsyncFn = (result: string) => timer(1000).pipe(map(() => result));
option | description |
---|---|
initialValue | set the initial value of your asyncFn |
defer | by default, your asyncFn will be call at initial or it changed. if you set defer to true, it will only run when you execute the run mehtod |
onStart | callback when asyncFn start, () => void |
onSuccess | callback when asyncFn success, (result) => void |
onFaulure | callback when asyncFn failure, (error: any) => void |
mapOperator | switchMap, concatMap , exhaustMap , mergeMap , flatMap, default is switchMap |
const delay = (ms: number) => new Promise(_ => setTimeout(_, ms));
Examples
import { useRxAsync } from 'use-rx-async';
function Component() {
const { data, loading, error, cancel, reset } = useRxAsync(asyncFn);
if (loading) {
return 'loading...';
}
if (error) {
return 'error!';
}
return data;
}
Examples
const asyncFnWithParam = (result: string) => delay(1000).then(() => result);
// wrap your default asyncFn with useCallback
function useHooks() {
const [result, setResult] = useState<string>();
const asyncFn = useCallback(() => {
return typeof result === 'string'
? asyncFnWithParam(result)
: Promise.reject();
}, [result]);
const { loading, data } = useRxAsync(asyncFn);
useEffect(() => {
setResult('Hello world');
}, []);
}
// Or set `defer` to true, if the asyncFn has parameters, you cannot set defer to false / undefined.
function useHooks() {
const { run } = useRxAsync(asyncFnWithParam, { defer: true });
useEffect(() => {
run('Hello World');
}, [run]);
}
import { timer } from 'rxjs';
import { delayWhen, retryWhen, take } from 'rxjs/operators';
const yourApiRequest = () => fetch('/api').then(res => res.json());
// if the request has errors, delay 1 second then retry up to 3 times
const asyncFn = () =>
from(yourApiRequest()).pipe(
retryWhen(errors =>
errors.pipe(
switchMap((error, index) =>
index === 3 ? throwError(error) : of(error)
),
delayWhen(() => timer(1000))
)
)
);
function Component() {
const state = useRxAsync(asyncFn);
// ....
}
const { data } = useRxAsync(apiRequest, {
initialValue: [],
});
// or
const { data = [] } = useRxAsync(apiRequest);
If you are axios user, you could use kuitos/axios-extensions