Roblox/rodux

Expose createReducer utility?

LPGhatguy opened this issue · 1 comments

Lua doesn't have pattern matching, so matching on a bunch of actions gives us a bunch of chained if statements that are kind of painful.

What Lua does have are great dictionaries, so it's possible we should expose a method like this Redux library called 'redux-create-reducer'.

In short:

local reducer = createReducer(initialState, {
    [Action.SetUsername] = function(state, action) {
        -- do something to create a new state
        return state
    }
})

Lua doesn't have pattern matching, so matching on a bunch of actions gives us a bunch of chained if statements that are kind of painful.

That's true if you're applying the Redux philosophy of using strings for action types, which you kind of have to do in JavaScript because associative arrays in JavaScript only supported string keys for the longest time.

Since Lua's great dictionaries support using objects as keys, I don't use string values for action.type; I use function references that reference action creators. Each reducer is then a simple dictionary that maps each action creator to its appropriate reducer function:

function createReducerForDriving()
  local actions = getActionCreatorsForDriving()
  local reducerFunctions = getReducerFunctionsForDriving()

  self.handlers = {}
  self.handlers[actions.increasedAcceleration] = reducerFunctions.increasedAcceleration
  self.handlers[actions.decreasedAcceleration] = reducerFunctions.decreasedAcceleration
  self.handlers[actions.appliedBrake] = reducerFunction.appliedBrake

  local consoleActions = getActionCreatorsForDrivingViaConsole()
  self.handlers[consoleActions.playerQuitGame] = reducerFunction.appliedBrake

  return function(state, action)
    local handler = self.handlers[action.type]

    if not handler then
      return state
    end

    return handler(state, action)
  end
end

Each action creator appends its own human-readable string name to the _name property of the returned action, for debugging purposes.

NOTE: This approach is not very portable across network calls.