Redux Dutiful Thunk
This is a Redux middleware almost the same as redux-thunk, but it respects Redux types.
Motivation
In Redux Thunk, you need to pass a thunk function directly to dispatch
to invoke it.
// An action creator for Redux Thunk. { return { ; };} // Dispatch a function.store;
But this becomes a problem if you want to write code in a type-safe manner
because the dispatch
function is supposed to accept Redux actions, not functions.
// A Redux action consists of a unique `type` and zero or more extra arguments. type: 'FETCH_USER' id: 30
So for example when you use Redux Thunk with TypeScript, you need to tweak Redux type definitions in some way (I don't know about flow much but I guess a similar problem exists). Therefore I could not find a good reason to use a function as a special action. Instead, let's create a normal action to meet the Redux rule and match its type definitions.
; { // Wrap your thunk function by `thunk`. return ;} // Now the action creator returns a normal action which contains a function you passed.console;//=> { type: '@@redux-dutiful-thunk/THUNK', thunk: f, } // So the `dispatch` function can take an action as usual, instead of a function.store;
The difference with Redux Thunk is only the thunk
wrapping.
function incrementAsync() {- return dispatch => {+ return thunk(async dispatch => { setTimeout(() => dispatch(increment()), 1000);- };+ }); }
Installation
npm install redux-dutiful-thunk
Usage
To enable Redux Dutiful Thunk, create a middleware and apply it to your store.
;;; const store = ;
Custom Argument
Like Redux Thunk, you can inject a custom argument to your thunk actions.
const store = ; { return ;}
With TypeScript
This library is written in TypeScript so the type definitions are provided.
To make your dispatch
function accept any thunk actions,
add AnyThunkAction
to your action type.
; ;
To implement your thunk action creators easily,
we recommend to define a Thunk
type using ThunkAction
.
;;;; ; // A thunk action creator.
Thunk's Return Value
Because the dispatch
function returns a given value as is,
you can get a return value of thunk function in Redux Thunk.
const user = await ;console;
But this cannot be done in Redux Dutiful Thunk.
// fetchUser returns an action, not a user data.const action = ;
For this use case, thunk actions have a promise that is resolved to a return value of your thunk function.
const action = ;const user = await actionpromise; // So you can write like thisuser = await promise;
Of course this promise is type safe.
Specifying Thunk Type
All thunk actions have a same action type.
If you want to distinguish each thunk action, use thunkAs
instead of thunk
.
This allows you to specify a thunk type.
; ;console.logaction.thunkType === 'FETCH_USER'; //=> true
API
Base types
-
Thunk<State, Action, Context, R>
R -
ThunkAction<State, Action, Context, R, T>
thunk
ThunkAction<S, A, C, R, null>
thunkAs
ThunkAction<S, A, C, R, T>
isThunkAction
action is AnyThunkAction
createThunkMiddleware
Middleware
See src/index.ts for details.