1- import { useCallback , useDebugValue , useEffect , useMemo , useRef , useState } from "react"
1+ import { useCallback , useDebugValue , useEffect , useMemo , useRef , useReducer } from "react"
2+ import { actions , init , reducer } from "./reducer"
3+
4+ const noop = ( ) => { }
25
36const useAsync = ( arg1 , arg2 ) => {
47 const counter = useRef ( 0 )
58 const isMounted = useRef ( true )
69 const lastArgs = useRef ( undefined )
710 const prevOptions = useRef ( undefined )
8- const abortController = useRef ( { abort : ( ) => { } } )
11+ const abortController = useRef ( { abort : noop } )
912
1013 const options = typeof arg1 === "function" ? { ...arg2 , promiseFn : arg1 } : arg1
1114 const { promise, promiseFn, deferFn, initialValue, onResolve, onReject, watch, watchFn } = options
1215
13- const [ state , setState ] = useState ( {
14- data : initialValue instanceof Error ? undefined : initialValue ,
15- error : initialValue instanceof Error ? initialValue : undefined ,
16- startedAt : promise || promiseFn ? new Date ( ) : undefined ,
17- finishedAt : initialValue ? new Date ( ) : undefined ,
18- } )
16+ const [ state , dispatch ] = useReducer ( reducer , options , init )
1917
20- const handleData = ( data , callback = ( ) => { } ) => {
18+ const setData = ( data , callback = noop ) => {
2119 if ( isMounted . current ) {
22- setState ( state => ( { ... state , data , error : undefined , finishedAt : new Date ( ) } ) )
23- callback ( data )
20+ dispatch ( { type : actions . fulfill , payload : data } )
21+ callback ( )
2422 }
2523 return data
2624 }
2725
28- const handleError = ( error , callback = ( ) => { } ) => {
26+ const setError = ( error , callback = noop ) => {
2927 if ( isMounted . current ) {
30- setState ( state => ( { ... state , error, finishedAt : new Date ( ) } ) )
31- callback ( error )
28+ dispatch ( { type : actions . reject , payload : error , error : true } )
29+ callback ( )
3230 }
3331 return error
3432 }
3533
36- const handleResolve = count => data => count === counter . current && handleData ( data , onResolve )
37- const handleReject = count => error => count === counter . current && handleError ( error , onReject )
34+ const handleResolve = count => data =>
35+ count === counter . current && setData ( data , ( ) => onResolve && onResolve ( data ) )
36+ const handleReject = count => error =>
37+ count === counter . current && setError ( error , ( ) => onReject && onReject ( error ) )
3838
3939 const start = ( ) => {
4040 if ( "AbortController" in window ) {
4141 abortController . current . abort ( )
4242 abortController . current = new window . AbortController ( )
4343 }
4444 counter . current ++
45- setState ( state => ( {
46- ...state ,
47- startedAt : new Date ( ) ,
48- finishedAt : undefined ,
49- } ) )
45+ dispatch ( { type : actions . start , meta : { counter : counter . current } } )
5046 }
5147
5248 const load = ( ) => {
@@ -79,7 +75,7 @@ const useAsync = (arg1, arg2) => {
7975 const cancel = ( ) => {
8076 counter . current ++
8177 abortController . current . abort ( )
82- setState ( state => ( { ... state , startedAt : undefined } ) )
78+ dispatch ( { type : actions . cancel , meta : { counter : counter . current } } )
8379 }
8480
8581 useEffect ( ( ) => {
@@ -104,14 +100,11 @@ const useAsync = (arg1, arg2) => {
104100 return useMemo (
105101 ( ) => ( {
106102 ...state ,
107- initialValue,
108- isLoading : state . startedAt && ( ! state . finishedAt || state . finishedAt < state . startedAt ) ,
109- counter : counter . current ,
110103 run,
111104 reload : ( ) => ( lastArgs . current ? run ( ...lastArgs . current ) : load ( ) ) ,
112105 cancel,
113- setData : handleData ,
114- setError : handleError ,
106+ setData,
107+ setError,
115108 } ) ,
116109 [ state ]
117110 )
@@ -152,5 +145,5 @@ const unsupported = () => {
152145 )
153146}
154147
155- export default ( useState ? useAsync : unsupported )
156- export const useFetch = useState ? useAsyncFetch : unsupported
148+ export default ( useEffect ? useAsync : unsupported )
149+ export const useFetch = useEffect ? useAsyncFetch : unsupported
0 commit comments