Created
September 10, 2020 18:56
-
-
Save felippepuhle/c1a6d55c6204eee8f0f1bb7027afc5c2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {useCallback, useReducer, useEffect, Reducer} from 'react'; | |
type GenericDataType = { | |
id: string; | |
}; | |
type Action<T extends GenericDataType> = { | |
type: 'PROCESS_ROW'; | |
payload: T; | |
}; | |
type State<T extends GenericDataType> = { | |
queue: T[]; | |
list: T[]; | |
}; | |
type Params<T extends GenericDataType> = { | |
initialList: T[]; | |
processRow: (data: T) => Promise<T>; | |
}; | |
const useAsyncQueue = <T extends GenericDataType>({ | |
initialList, | |
processRow, | |
}: Params<T>): State<T> => { | |
const reducer: Reducer<State<T>, Action<T>> = useCallback((state, action) => { | |
switch (action.type) { | |
case 'PROCESS_ROW': | |
return { | |
...state, | |
queue: state.queue.filter((row) => row.id !== action.payload.id), | |
list: state.list.map((row) => { | |
if (row.id !== action.payload.id) { | |
return row; | |
} | |
return action.payload; | |
}), | |
}; | |
default: | |
return state; | |
} | |
}, []); | |
const [state, dispatch] = useReducer(reducer, { | |
queue: initialList, | |
list: initialList, | |
}); | |
const processQueue = useCallback(async () => { | |
if (state.queue.length === 0) { | |
return; | |
} | |
const row = state.queue[0]; | |
const payload = await processRow(row); | |
dispatch({ | |
type: 'PROCESS_ROW', | |
payload, | |
}); | |
}, [processRow, state.queue, dispatch]); | |
useEffect(() => { | |
processQueue(); | |
}, [processQueue]); | |
return state; | |
}; | |
export default useAsyncQueue; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment