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,
})