diff --git a/README.md b/README.md index 5db9dc5..bc1f7a3 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,59 @@ const { } = updux; ``` +## Mapping a mutation to all values of a state + +Say you have a `todos` state that is an array of `todo` sub-states. It's easy +enough to have the main reducer maps away all items to the sub-reducer: + +``` +const todo = new Updux({ + mutations: { + review: () => u({ reviewed: true}), + done: () => u({done: true}), + }, +}); + +const todos = new Updux({ initial: [] }); + +todos.addMutation( + todo.actions.review, + (_,action) => state => state.map( todo.upreducer(action) ) +); +todos.addMutation( + todo.actions.done, + (id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))), +); + +``` + +But `updeep` can iterate through all the items of an array (or the values of +an object) via the special key `*`. So the todos updux above could also be +written: + +``` +const todo = new Updux({ + mutations: { + review: () => u({ reviewed: true}), + done: () => u({done: true}), + }, +}); + +const todos = new Updux({ + subduxes: { '*': todo }, +}); + +todos.addMutation( + todo.actions.done, + (id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))), + true +); +``` + +The advantages being that the actions/mutations/effects of the subdux will be +imported by the root updux as usual, and all actions that aren't being +overridden by a sink mutation will trickle down automatically. + ## Usage with Immer While Updux was created with Updeep in mind, it also plays very diff --git a/src/buildMutations/index.ts b/src/buildMutations/index.ts index c1b6420..d20f77a 100644 --- a/src/buildMutations/index.ts +++ b/src/buildMutations/index.ts @@ -50,8 +50,6 @@ function buildMutations( nonGlobby.forEach(([slice, {mutations = {}, reducer = {}}]:any[]) => { Object.entries(mutations).forEach(([type, mutation]) => { const localized = (payload = null, action :Action) => { - console.log(slice); - return u.updateIn(slice)((mutation as Mutation)(payload, action)); } diff --git a/src/mappedUpdux.test.ts b/src/mappedUpdux.test.ts new file mode 100644 index 0000000..ee5d2fc --- /dev/null +++ b/src/mappedUpdux.test.ts @@ -0,0 +1,29 @@ +import Updux from './updux'; +import u from 'updeep'; + +const todo = new Updux({ + mutations: { + review: () => u({ reviewed: true}), + done: () => u({done: true}), + }, +}); + +const todos = new Updux({ + subduxes: { '*': todo }, +}); + +todos.addMutation( + todo.actions.done, (id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))), true +); + +test( '* for mapping works', () => { + const reducer = todos.reducer; + let state = [ { id: 0 }, {id: 1 } ]; + state = reducer( state, todos.actions.review() ); + state = reducer( state, todos.actions.done(1) ); + + expect(state).toEqual([ + { id: 0, reviewed: true }, + { id: 1, reviewed: true, done: true }, + ]); +});