Leaf reducers
A leaf reducer is a function or configuration object that updates the state of an arbitrary leaf in your state tree.
They are:
- passed into
reduxLeaves
with a uniquecreatorKey
as part ofreducersDict
; and - triggered at an arbitrary leaf only by dispatching an action created by the leaf's
create[creatorKey]
method.
Syntax
Function (shorthand)
const shorthandFunction = (leafState, action, treeState) => {
// some logic here
// return the new leafState
}
Configuration object (longhand)
The above leafReducer function is shorthand for a configuration object with presets:
const longhandConfig = {
reducer: shorthandFunction,
// below are the configuration keys and their default values
argsToPayload: firstArgOnly => firstArgOnly,
// by default, if the action creator is invoked with arguments,
// the first argument only becomes the action's payload property.
}
Using the configuration object longhand allows greater customisation, through additional configuration keys.
Configuration keys
The list of configuration keys that can be provided are below:
Key | Value (type) | Description | Optional? |
---|---|---|---|
reducer | function | Updates the leaf's state | |
argsToPayload | function | Converts action creator arguments to an action payload | Optional |
reducer
(function): Updates the leaf's state.
Arguments
leafState
(any): the current state of the given leafaction
(object): the action createdtreeState
(object): the current state of the entire Redux store
Returns
The new state value for the leaf.
argsToPayload
(function, optional): Converts action creator arguments to an action payload.
Default behaviour: if a first argument is provided, it is supplied as the action's payload. All other arguments are discarded.
Arguments
...args
: the arguments supplied to an action creator that triggersreducer
Returns
A payload
used by the action creator.
Examples
// Action payload is the first argument only (default behaviour)
const firstArgToPayload = firstArgOnly => firstArgOnly
// Action payload as an array of the first 5 arguments
const firstFiveArgsToPayload = (...args) => args.slice(0, 5)
// Action payload as an object
const spreadArgsToObjectPayload = (first, second, ...rest) => ({ first, second, rest })
We can check that these are behaving as expected:
// Test them out by creating actions using reduxLeaves
const returnPayload = (leafState, { payload }) => payload
[
firstArgToPayload,
firstFiveArgsToPayload,
spreadArgsToObjectPayload
].forEach(argsToPayload => {
// Use each as an argsToPayload
const returnPayload = {
reducer: (leafState, { payload }) => payload,
argsToPayload
}
const [reducer, actions] = reduxLeaves({}, { returnPayload })
// log out the payload for an action passed seven arguments
console.log(actions.create.returnPayload(1, 2, 3, 4, 5, 6, 7).payload)
})
// 1
// [1, 2, 3, 4, 5]
// { first: 1, second: 2, rest: [3, 4, 5, 6, 7] }