Last active
March 9, 2020 18:21
-
-
Save vhuerta/ff46f9ddf2af2ad1a03938877473c484 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, Reducer, ReducerState, ReducerAction } from "react"; | |
| import { useReducer } from "reinspect"; | |
| export type StateGetter<A extends Reducer<any, any>> = () => ReducerState<A>; | |
| export type DispatchThunk<A extends Reducer<any, any>> = ( | |
| dispatch: (value: ReducerAction<A>) => void, | |
| state: StateGetter<A> | |
| ) => void; | |
| export type DispatcherThunk<A extends Reducer<any, any>> = ( | |
| action: ReducerAction<A> | DispatchThunk<A> | |
| ) => void; | |
| export type ActionOrThunk<A extends Reducer<any, any>> = | |
| | ReducerAction<A> | |
| | DispatchThunk<A>; | |
| function isDispatchThunk<R extends Reducer<any, any>>( | |
| action: ReducerAction<R> | DispatchThunk<R> | |
| ): action is DispatchThunk<R> { | |
| return typeof action === "function"; | |
| } | |
| /** | |
| * Augments React's useReducer() hook so that the action | |
| * dispatcher supports thunks. | |
| */ | |
| export function useThunkReducer<R extends Reducer<any, any>>( | |
| reducer: R, | |
| initialState: ReducerState<R>, | |
| id: string | |
| ): [ReducerState<R>, DispatcherThunk<R>] { | |
| const [state, dispatch] = useReducer( | |
| reducer, | |
| initialState, | |
| state => state, | |
| id | |
| ); | |
| const getState = useCallback(() => state, [state]); | |
| const dispatchThunk = (action: ActionOrThunk<R>): void => { | |
| return isDispatchThunk(action) | |
| ? action(dispatch, getState) | |
| : dispatch(action); | |
| }; | |
| return [state, dispatchThunk]; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment