Add Rodux.createAction
Closed this issue · 4 comments
We should introduce a more standardized way of creating and using Rodux actions to prevent common errors and more closely associate actions with the reducers that handle them. A file defining an action would look like this:
-- necessary requires to include Rodux
return Rodux.createAction(script.name, function(value)
return {
value = value,
}
end)
Dispatching that action would look like this:
local MyAction = require(Actions.MyAction)
-- ...
store:Dispatch(MyAction(value))
A reducer that handles this action would look like this:
local MyAction = require(Actions.MyAction)
-- ...
if action.type == MyAction.name then
-- change some state!
end
We should model Rodux.createAction
off of the following Action.lua
implementation:
return function(name, fn)
assert(type(name) == "string", "A name must be provided to create an Action")
assert(type(fn) == "function", "A function must be provided to create an Action")
return setmetatable({
name = name,
}, {
__call = function(self, ...)
local result = fn(...)
assert(type(result) == "table", "An action must return a table")
result.type = name
return result
end
})
end
I kind of like the fact that this proposal
- Mirrors
Rodux.createReducer
- Does not affect users' ability to use actions normally
Having a formal pattern for this at least as an option might be nice. Action is a thing I copy into a lot of projects in order to use it specifically with Rodux.
I also often like to add something like this to the __call
function in the sample implementation that @SlartibartfastFjords provided:
setmetatable(result, {
__index = function(table, key)
error("Attempted to access nonexistent key " .. tostring(key) .. " on action " .. name, 2)
end
})
That way if I ever make typos in reducers I'll find it right away instead of quietly setting things to nil
.
We have to be careful with trying to define when table indexes are mistakes, since Lua doesn't differentiate between a value in a table being nil
and it being an invalid key!
Right, I agree. I find it useful for my cases, but it's too presumptive to put in a common version. I think having one at all would be nice though.
I'd like to bring this issue up again. I think since this helper is used as the standard way to create actions across so many different projects it seems sufficiently useful to add to the core Rodux API. This would stop this action helper being duplicated in so many different places. Alternatively we could make a separate action helper package but I think this will be harder to discover than something in the Rodux API.