Skip to content

Latest commit

 

History

History
71 lines (52 loc) · 2.54 KB

intermediateExample.md

File metadata and controls

71 lines (52 loc) · 2.54 KB
id title hide_title sidebar_label
intermediate-example
Intermediate example
true
Intermediate example

Intermediate example: custom logic

Play around with this code on Runkit

Situation: I want to define a general type of reducer logic that can be reused on any arbitrary slice of state.

Complication: I want to do this as quickly, painlessly and intuitively as possible.

Question: Do I really have to create sub-reducers with the same underlying logic?

Answer: no! Just provide Redux-Leaves once with your custom reducer logic, and you can automatically use it at any leaf of your state tree.

Demonstration

Set up with your custom reducer logic

import { createStore } from 'redux'
import reduxLeaves from 'redux-leaves'

const initialState = {
  counter: 2,
  list: ['first', 'second'],
  nested: { arbitrarily: { deep: 0 } }
}

// Key your reducer logic by a descriptive verb
const reducersDict = {
  double: leafState => leafState * 2,
  appendToEach: (leafState, action) => leafState.map(str => str.concat(action.payload)),
  countTreeKeys: (leafState, action, treeState) => Object.keys(treeState).length
}

// Provide the dictionary of your reducer logic to reduxLeaves
const [reducer, actions] = reduxLeaves(initialState, reducersDict)
const store = createStore(reducer)

Dispatch actions at any leaf with the corresponding keys

store.dispatch(actions.counter.create.double())
console.log(store.getState().counter) // 4

store.dispatch(actions.list.create.appendToEach(' item')) // ' item' will be the action payload
console.log(store.getState().list) // ['first item', 'second item']

store.dispatch(actions.nested.arbitrarily.deep.create.countTreeKeys())
console.log(store.getState().nested.arbitrarily.deep) // 3

// And to demonstrate reusing logic at an arbitrary leaf:
store.dispatch(actions.nested.arbitrarily.deep.create.double())
console.log(store.getState().nested.arbitrarily.deep) // 6

Default handling of arguments

When you supply reduxLeaves with custom reducer logic, it provides the corresponding action creators, e.g. actions.list.create.appendToEach used above.

The default behaviour of these action creators is that, if they receive any arguments, only the first argument is passed to the created action as a payload:

const actionToAppend = actions.list.create.appendToEach('foo', 'bar')
console.log(actionToAppend.payload) // 'foo'

If you would like to customise this behaviour, look at the advanced example.