|
| 1 | +When you initialize your `store` with [`Store.new`](../api-reference.md#storenew), you provide a single function called a `reducer` which will consume any `action` dispatched to your `store` and create a new `state` object based on the current `state` of your `store`. |
| 2 | + |
| 3 | +```lua |
| 4 | +local phoneNumberReducer = function(state, action) |
| 5 | + if action.type == "ReceivedNewPhoneNumber" then |
| 6 | + return action.phoneNumber |
| 7 | + end |
| 8 | + |
| 9 | + return state |
| 10 | +end |
| 11 | +``` |
| 12 | + |
| 13 | +Note that `state` is never actually modified by our `reducer`. The `state` of our `store` is *read-only*, so our `reducer` must construct a new `state` object in response to the received `action`. |
| 14 | + |
| 15 | +For complex applications, it is often useful to break down the global `reducer` you provide to the `store` into a set of smaller `reducer` functions, each of which is responsible for a portion of the `state`. |
| 16 | + |
| 17 | +```lua |
| 18 | +local friendsReducer = function(state, action) |
| 19 | + --[[ |
| 20 | + The state might be nil the first time this reducer is executed. |
| 21 | + In that case, we need to initialize our state to be the empty table. |
| 22 | + ]] |
| 23 | + state = state or {} |
| 24 | + |
| 25 | + if action.type == "MadeNewFriends" then |
| 26 | + local newState = {} |
| 27 | + |
| 28 | + -- Since state is read-only, we copy it into newState |
| 29 | + for index, friend in ipairs(state) do |
| 30 | + newState[index] = friend |
| 31 | + end |
| 32 | + |
| 33 | + for _, friend in ipairs(action.newFriends) |
| 34 | + table.insert(newState, friend) |
| 35 | + end |
| 36 | + |
| 37 | + return newState |
| 38 | + end |
| 39 | + |
| 40 | + return state |
| 41 | +end |
| 42 | + |
| 43 | +--[[ |
| 44 | + note that the reducer for our entire application is defined by a table of |
| 45 | + sub-reducers where each sub-reducer is responsible for one portion of the |
| 46 | + overall state. |
| 47 | +]] |
| 48 | +local reducer = function(action, state) |
| 49 | + return { |
| 50 | + myPhoneNumber = phoneNumberReducer(state.myPhoneNumber, action), |
| 51 | + myFriends = friendsReducer(state.myFriends, action), |
| 52 | + } |
| 53 | +end |
| 54 | +``` |
| 55 | + |
| 56 | +Alternatively, you can use [`Rodux.createReducer`](../api-reference.md#roduxcreatereducer) and [`Rodux.combineReducers`](../api-reference.md#roduxcombinereducers) to generate the same code as seen above. Using `Rodux.createReducer` and `Rodux.combineReducers` to create your `reducer` functions isn't as verbose and is less prone to developer error. |
| 57 | + |
| 58 | +```lua |
| 59 | +local phoneNumberReducer = Rodux.createReducer(nil, { |
| 60 | + ReceivedNewPhoneNumber = function(state, action) |
| 61 | + return action.phoneNumber |
| 62 | + end, |
| 63 | +}) |
| 64 | + |
| 65 | +local friendsReducer = Rodux.createReducer({}, { |
| 66 | + MadeNewFriends = function(state, action) |
| 67 | + local newState = {} |
| 68 | + |
| 69 | + -- Since state is read-only, we copy it into newState |
| 70 | + for index, friend in ipairs(state) do |
| 71 | + newState[index] = friend |
| 72 | + end |
| 73 | + |
| 74 | + for _, friend in ipairs(action.friends) |
| 75 | + table.insert(newState, friend) |
| 76 | + end |
| 77 | + |
| 78 | + return newState |
| 79 | + end, |
| 80 | +}) |
| 81 | + |
| 82 | +local reducer = Rodux.combineReducers({ |
| 83 | + myPhoneNumber = phoneNumberReducer, |
| 84 | + myFriends = friendsReducer, |
| 85 | +}) |
| 86 | +``` |
0 commit comments