updux/docs-docsidy/recipes.md
2024-08-08 09:28:44 -04:00

2.0 KiB

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.

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
    }
});