Browse Source

useMountedRef

redux
YuJian920 3 years ago
parent
commit
dfe7611616
  1. 45
      src/hook/useAsync.ts

45
src/hook/useAsync.ts

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
import { useCallback, useState } from "react";
import { useCallback, useReducer, useState } from "react";
import useMountedRef from "./useMountedRef";
interface State<D> {
@ -17,32 +17,49 @@ const defaultConfig = { @@ -17,32 +17,49 @@ const defaultConfig = {
throwOnError: false,
};
const useSafeDispatch = <T>(dispatch: (...args: T[]) => void) => {
const mountedRef = useMountedRef();
return useCallback(
(...args: T[]) => {
mountedRef.current && dispatch(...args);
},
[mountedRef, dispatch]
);
};
const useAsync = <D>(
initialState?: State<D>,
initialConfig?: typeof defaultConfig
) => {
const config = { ...defaultConfig, initialConfig };
const [state, setState] = useState<State<D>>({
...defaultInitialState,
...initialState,
});
const mountedRef = useMountedRef();
const [state, dispatch] = useReducer(
(state: State<D>, action: Partial<State<D>>) => ({ ...state, ...action }),
{
...defaultInitialState,
...initialState,
}
);
const safeDispatch = useSafeDispatch(dispatch);
const setData = useCallback(
(data: D) => setState({ data, stat: "success", error: null }),
[]
(data: D) => safeDispatch({ data, stat: "success", error: null }),
[safeDispatch]
);
const setError = useCallback(
(error: Error) => {
safeDispatch({ data: null, stat: "error", error });
},
[safeDispatch]
);
const setError = useCallback((error: Error) => {
setState({ data: null, stat: "error", error });
}, []);
const run = useCallback(
(promise: Promise<D>) => {
if (!promise || !promise.then) throw new Error("请传入 Promise 数据类型");
setState((prevState) => ({ ...prevState, stat: "loading" }));
safeDispatch({ stat: "loading" });
return promise
.then((data) => {
if (mountedRef.current) setData(data);
setData(data);
return data;
})
.catch((error) => {
@ -51,7 +68,7 @@ const useAsync = <D>( @@ -51,7 +68,7 @@ const useAsync = <D>(
return error;
});
},
[config.throwOnError, mountedRef, setData, setData, setError]
[config.throwOnError, setData, setData, safeDispatch, setError]
);
return {

Loading…
Cancel
Save