composable-reducer
v0.2.0
Published
Create composable reducers on the fly from objects
Downloads
2
Maintainers
Readme
🧱 composable-reducer
Create composable reducers on the fly from objects
First and foremost, composableReducer
is a helper that lets developers create reducers on the fly from objects and their key => value
pairs, where key
s are the dispatch
types, thus reducing the boilerplate you have to write while creating reducers to use with React's useReducer
hook.
Each function returns only the piece of state it wants to modify. I call these micro-reducers.
Each micro-reducer can be used inside a composed-reducer (hah! composable-reducer
, who would've guessed?) creating a chain. These are just reducers that when called call their micro-reducers in the order they're defined. Every micro-reducer receives the full state mixed with the updated bits created by the previous micro-reducers, this way every micro-reducer can have access to an up-to-date state.
Throw in the mix the possibility to define aliases for micro-reducers and composed-reducers, the possibility to pass static arguments around (e.g. addOne: 'add({ "amount": 1 })'
, where add
is just a micro-reducer), and you have a pretty powerful utility in your hands☝🏼. The best part about the static-arguments thing? They have the highest priority (i.e. they can't be overridden), can be used in aliases for composed-reducers, and are thrown away after being used, so they don't pollute your micro-reducer chain!
☝🏼: Seriously, you can extract all the business logic from a component and add features just by adding micro-reducers and composed-reducers, give it a try!
Features
- Create a reducer on the fly from an
object
'skey
s andvalue
s. - Define composed-reducers using micro-reducers.
- Create aliases for reducers, even for the composed ones.
- Use static arguments for aliases and elements of composed reducers.
- Throws an error at reducer-build-time if aliases mismatch.
- Throws an error when a
dispatch
type is not recognized.
Install
$ npm install composable-reducer
Or if you prefer using Yarn:
$ yarn add composable-reducer
Usage
import { composableReducer } from "composable-reducer"
const reducer = composableReducer({
setDiscountPercentage: (_, { percentage }) => ({
percentage,
}),
percentage: ({ percentage, price }) => ({
discount: (percentage / 100) * price,
}),
decrease: ({ discount, price }) => ({
discountedPrice: price - discount,
}),
setLabel: (_, { label }) => ({
label,
}),
setDiscountedPrice: [
"setDiscountPercentage",
"percentage",
"decrease",
'setLabel({ "label": "Sales!" })',
],
})
reducer({ price: 50 }, { type: "setDiscountedPrice", percentage: 20 })
// => { price: 50, percentage: 20, discount: 10, discountedPrice: 40, label: 'Sales!' }
const Component = ({ price }) => {
const [{ price, discountedPrice = price }, dispatch] = useReducer(reducer, {
price: price,
})
useTimeout(
() => dispatch({ type: "setDiscountedPrice", percentage: 20 }),
5000
)
return (
<>
{discountedPrice < price && <del>{price}</del>} {discountedPrice}
</>
)
}
API
composableReducer(object, options)
Create a reducer from object
by using its key => value
pairs, where key
s are the dispatch
types and value
s are their handlers. Read more about micro-reducers and composed-reducers above.
object
Type: object
options
Type: object
options.actionKey
Type: string
Default Value: "type"
The dispatch
property that should be used to distinguish between different dispatch
es, by default it's "type"
, e.g. dispatch({ type: 'add' })
.
Browser support
The latest version of Chrome, Firefox, Safari, and Edge. I think that Edge 12 is the lowest you can go.