document the mapping behavior of a '*' subdux

This commit is contained in:
Yanick Champoux 2019-11-05 19:44:40 -05:00
parent 0d298cb285
commit 47b78f43cc
3 changed files with 82 additions and 2 deletions

View File

@ -123,6 +123,59 @@ const {
} = updux; } = 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 ## Usage with Immer
While Updux was created with Updeep in mind, it also plays very While Updux was created with Updeep in mind, it also plays very

View File

@ -50,8 +50,6 @@ function buildMutations(
nonGlobby.forEach(([slice, {mutations = {}, reducer = {}}]:any[]) => { nonGlobby.forEach(([slice, {mutations = {}, reducer = {}}]:any[]) => {
Object.entries(mutations).forEach(([type, mutation]) => { Object.entries(mutations).forEach(([type, mutation]) => {
const localized = (payload = null, action :Action) => { const localized = (payload = null, action :Action) => {
console.log(slice);
return u.updateIn(slice)((mutation as Mutation)(payload, action)); return u.updateIn(slice)((mutation as Mutation)(payload, action));
} }

29
src/mappedUpdux.test.ts Normal file
View File

@ -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 },
]);
});