Akin to redux-thunk,
useThunkReducer()
augments React'suseReducer()
hook so that the action dispatcher supports thunks. Now, you can write action creators that return a function rather than an action!Requires React v16.8 and above.
npm install react-hook-thunk-reducer
Then just import it and use it like you would React.useReducer()
.
import { useThunkReducer } from 'react-hook-thunk-reducer';
function Component({ initialState }) {
const [state, dispatch] = useThunkReducer(reducer, initialState);
// ...
}
Create your actions just like you would in Redux. Similar to redux-thunk, if an action returns a function, it's treated as a thunk and has access to the current state.
function increment() {
return {
type: 'increment'
};
}
function incrementIfOdd() {
return (dispatch, getState) => {
const { count } = getState();
if (count % 2 !== 0) {
dispatch(increment());
}
};
}
Create your functional component and call the useThunkReducer()
hook as if it were React.useReducer()
;
import { useThunkReducer } from 'react-hook-thunk-reducer';
// ...
function reducer(state, action) {
switch (action.type) {
case 'increment':
return { count: state.count + 1 };
default:
throw new Error();
}
}
function Counter({ initialState }) {
const [state, dispatch] = useThunkReducer(reducer, initialState);
// ...
return (
<>
Count: {state.count}
<button onClick={onButtonPress}>+</button>
</>
);
}
Dispatch your actions using the augmented dispatch
function.
const onButtonPress = () => {
dispatch(incrementIfOdd());
};
The value of the inner function will be returned when dispatching thunks.
function incrementAndReturnCount() {
return (dispatch, getState) => {
dispatch(increment());
return getState().count;
};
}
const newCount = dispatch(incrementAndReturnCount());