# Recipes ## Mapping a mutation to all values of a state Say you have a `todos` state that is an array of `todo` sub-states, with some actions that should percolate to all todos, and some that should only percolate to one. One way to model this is via updux's splat subduxes (backed by `updeep`'s own '*'-key behavior). ``` const done = () => (state) => ({...state, done: true}); const todo = new Updux({ initial: { id: 0, done: false }, actions: { done: null, doneAll: null, }, mutations: { done, doneAll: done, }, }); const todos = new Updux({ initial: [], subduxes: { '*': todo }, actions: { addTodo: null }, mutations: { addTodo: text => state => [ ...state, { text } ] } }); todos.setMutation( todo.actions.done, (text,action) => u.map(u.if(u.is('text',text), todo.upreducer(action))), true // prevents the subduxes mutations to run automatically ); ``` ## Usage with Immer While Updux was created with Updeep in mind, it also plays very well with [Immer](https://immerjs.github.io/immer/docs/introduction). For example, taking this basic updux: ``` import Updux from 'updux'; const updux = new Updux({ initial: { counter: 0 }, mutations: { add: (inc=1) => state => ({ counter: state.counter + inc }) } }); ``` Converting it to Immer would look like: ``` import Updux from 'updux'; import { produce } from 'immer'; const updux = new Updux({ initial: { counter: 0 }, mutations: { add: (inc=1) => produce( draft => draft.counter += inc ) } } }); ``` But since typing `produce` over and over is no fun, `groomMutations` can be used to wrap all mutations with it: ``` import Updux from 'updux'; import { produce } from 'immer'; const updux = new Updux({ initial: { counter: 0 }, groomMutations: mutation => (...args) => produce( mutation(...args) ), mutations: { add: (inc=1) => draft => draft.counter += inc } }); ```