Reducers
When you initialize your store with Store.new, 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.
local phoneNumberReducer = function(state, action)
if action.type == "ReceivedNewPhoneNumber" then
return action.phoneNumber
end
return state
end
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.
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.
local friendsReducer = function(state, action)
--[[
The state might be nil the first time this reducer is executed.
In that case, we need to initialize our state to be the empty table.
]]
state = state or {}
if action.type == "MadeNewFriends" then
local newState = {}
-- Since state is read-only, we copy it into newState
for index, friend in ipairs(state) do
newState[index] = friend
end
for _, friend in ipairs(action.newFriends)
table.insert(newState, friend)
end
return newState
end
return state
end
--[[
note that the reducer for our entire application is defined by a table of
sub-reducers where each sub-reducer is responsible for one portion of the
overall state.
]]
local reducer = function(state, action)
return {
myPhoneNumber = phoneNumberReducer(state.myPhoneNumber, action),
myFriends = friendsReducer(state.myFriends, action),
}
end
Alternatively, you can use Rodux.createReducer and Rodux.combineReducers 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.
local phoneNumberReducer = Rodux.createReducer(nil, {
ReceivedNewPhoneNumber = function(state, action)
return action.phoneNumber
end,
})
local friendsReducer = Rodux.createReducer({}, {
MadeNewFriends = function(state, action)
local newState = {}
-- Since state is read-only, we copy it into newState
for index, friend in ipairs(state) do
newState[index] = friend
end
for _, friend in ipairs(action.friends)
table.insert(newState, friend)
end
return newState
end,
})
local reducer = Rodux.combineReducers({
myPhoneNumber = phoneNumberReducer,
myFriends = friendsReducer,
})