const defaultInitialState = {status: ‘idle‘, data: null, error: null} export function useAsync(initialState) { const initialStateRef = React.useRef({ ...defaultInitialState, ...initialState, }) const [{status, data, error}, setState] = React.useReducer( (s, a) => ({...s, ...a}), initialStateRef.current, ) const safeSetState = useSafeDispatch(setState) const run = React.useCallback( promise => { if (!promise || !promise.then) { throw new Error( `The argument passed to useAsync().run must be a promise. Maybe a function that‘s passed isn‘t returning anything?`, ) } safeSetState({status: ‘pending‘}) return promise.then( data => { safeSetState({data, status: ‘resolved‘}) return data }, error => { safeSetState({status: ‘rejected‘, error}) return error }, ) }, [safeSetState], ) const setData = React.useCallback(data => safeSetState({data}), [ safeSetState, ]) const setError = React.useCallback(error => safeSetState({error}), [ safeSetState, ]) const reset = React.useCallback(() => safeSetState(initialStateRef.current), [ safeSetState, ]) return { // using the same names that react-query uses for convenience isIdle: status === ‘idle‘, isLoading: status === ‘pending‘, isError: status === ‘rejected‘, isSuccess: status === ‘resolved‘, setData, setError, error, status, data, run, reset, } }
Using:
const {data: items, run} = useAsync({data: [], status: ‘pending‘}) React.useEffect(() => { run(getItems(inputValue)) }, [inputValue, run])
原文:https://www.cnblogs.com/Answer1215/p/13861838.html