1 | import { bindActionCreators } from 'redux';
|
2 |
|
3 | /** @typedef {{ [key: string]: (Function | CreatorObject) }} CreatorObject */
|
4 |
|
5 | /**
|
6 | * Returns a function to bind action creators based on the shape of the value.
|
7 | *
|
8 | * Redux's `bindActionCreators` expects a function or an object whose values
|
9 | * are functions. Since our action creators are exported as nested objects,
|
10 | * whose values may be objects, we invoke `bindActionCreators` recursively.
|
11 | *
|
12 | * @param {Function | CreatorObject} value - Action creator(s) to be bound.
|
13 | * @return {Function} - A function compatible with `value`.
|
14 | */
|
15 | const getBindFunction = value =>
|
16 | typeof value === 'function'
|
17 | ? bindActionCreators
|
18 | : bindActionCreatorsRecursively;
|
19 |
|
20 | /**
|
21 | * Maps an object whose values are action creators (or objects of such)
|
22 | * into an object whose values are bound action creators (or objects of such).
|
23 | *
|
24 | * A bound action creator is one wrapped into a `dispatch` call,
|
25 | * such that invoking it creates and dispatches an action.
|
26 | *
|
27 | * Note that `actions` may not be a function.
|
28 | *
|
29 | * @param {CreatorObject} actions - A nested object containing action creators.
|
30 | * @param {Function} dispatch - The `dispatch` function from a Redux store.
|
31 | * @return {CreatorObject} - A nested object containing bound action creators.
|
32 | */
|
33 | const bindActionCreatorsRecursively = (actions, dispatch) =>
|
34 | Object.entries(actions).reduce((acc, [name, value]) => {
|
35 | const bind = getBindFunction(value);
|
36 | acc[name] = bind(value, dispatch);
|
37 | return acc;
|
38 | }, {});
|
39 |
|
40 | export default bindActionCreatorsRecursively;
|