1 | # r/middleware
|
2 | Helpful Redux middleware
|
3 |
|
4 | ## Installation
|
5 | Install via npm.
|
6 |
|
7 | `npm install -S @r/middleware`
|
8 |
|
9 | ## Modules
|
10 | @r/middleware exports two middlewares: `Thunker` and `PromiseWell`;
|
11 |
|
12 | ### Thunker
|
13 | Thunker expands on a traditional Redux thunk utility. Namely, it requires that the thunking action returns a promise. As a result, it becomes easier to know when the thunked actions have completed: when the promise resolves, all thunked actions have fired.
|
14 |
|
15 | ```es6
|
16 | // Initializing a Thunker
|
17 | import Thunker from '@r/middleware/Thunker';
|
18 |
|
19 | const thunk = Thunker.create();
|
20 |
|
21 | // in Redux
|
22 | applyMiddleware(..., thunk, ...);
|
23 | ```
|
24 |
|
25 | To simplify using Thunker, it is highly recommended es7 style async functions are used.
|
26 |
|
27 | ```es6
|
28 | // example thunked action
|
29 |
|
30 | const getData = () => async (dispatch, getState, utils) => {
|
31 | // immediately dispatch synchronous actions as normal
|
32 | dispatch(/* sync action */);
|
33 |
|
34 | // wait for data if need be
|
35 | const { foo, bar } = await asyncFunctionCall();
|
36 |
|
37 | // continue to dispatch as normal
|
38 | dispatch(/* another action */);
|
39 | };
|
40 | ```
|
41 |
|
42 | Thunker performs an additional task. Many times, it becomes necessary to wait for some piece of state to update, or to wait for a particular action to be dispatched before another action is dispatched. Thunker solves this by surfacing two utility methods: `waitForState` and `waitForAction`. Both return a promise that can be `await`-ed on.
|
43 |
|
44 | #### waitForState
|
45 |
|
46 | ```
|
47 | waitForState(stateFn: Function, cb: Function [, stateFailedFn: Function]): Promise
|
48 | ```
|
49 |
|
50 | `stateFn(state: Object): Boolean`
|
51 |
|
52 | A function that creates the condition that must be met for the callback to fire. Receives a copy of state as its argument. Expected to return a truthy/falsey value.
|
53 |
|
54 | `cb(state: Object): void`
|
55 |
|
56 | A function that is called when the conditional is met. Receives a copy of state as its argument.
|
57 |
|
58 | `stateFailedFn(state: Object): void` (OPTIONAL)
|
59 |
|
60 | A function that is called the *first* time the conditional is *not* met. Only fires once. Receives a copy of state as its argument.
|
61 |
|
62 |
|
63 | #### waitForAction
|
64 |
|
65 | ```
|
66 | waitForAction(actionFn: Function, cb: Function): Promise
|
67 | ```
|
68 |
|
69 | `actionFn: Function(action: Object)`
|
70 |
|
71 | A function that receives a Redux action, represents the condition that must be met for the callback to fire. *After* `waitForAction` is invoked, if `action` is dispatched, the callback will fire.
|
72 |
|
73 | `cb(state: Object): void`
|
74 |
|
75 | A function that is called when the `action` is dispatched. Receives a copy of state as its argument.
|
76 |
|
77 | ### PromiseWell
|
78 | The PromiseWell merely collects promises that dispatched by other middleware. It should be one of the last middleware invoked.
|
79 |
|
80 | ```es6
|
81 | // Initializing a PromiseWell
|
82 | import PromiseWell from '@r/middleware/PromiseWell';
|
83 |
|
84 | const well = PromiseWell.create();
|
85 |
|
86 | // in Redux
|
87 | applyMiddleware(..., well.middleware, ...);
|
88 |
|
89 | // on the server side
|
90 | await well.onComplete();
|
91 | ```
|
92 |
|
93 | In addition to capturing promises, the PromiseWell lets you query to check if all the captured promises have been completed through the use of `onComplete`.
|