# Tutorial This tutorial walks you through the features of `Updux` using the time-honored example of the implementation of Todo list store. We'll be using [updeep](https://www.npmjs.com/package/updeep) to help with immutability and deep merging, but that's totally optional. If `updeep` is not your bag, it can easily be substitued with, say, [immer][], [lodash][], or even plain JavaScript. ## Definition of the state To begin with, let's define that has nothing but an initial state. ```js import { Updux } from 'updux'; const todosDux = new Updux({ initial: { next_id: 1, todos: [], } }); ``` Congrats! You have written your first Updux object. It doesn't do a lot, but you can already create a store out of it, and its initial state will be automatically set: ```js const store = todosDux.createStore(); console.log(store.getState()); // prints { next_id: 1, todos: [] } ``` ## Add actions This is all good, but a little static. Let's add actions! ```js const todosDux = new Updux({ initial: { next_id: 1, todos: [], }, { addTodo: null, todoDone: null, } }); ``` ### Accessing actions Once an action is defined, its creator is accessible via the `actions` accessor. ```js console.log( todosDux.actions.addTodo('write tutorial') ); // prints { type: 'addTodo', payload: 'write tutorial' } ``` ### Adding a mutation Mutations are the reducing functions associated to actions. They are defined via the `setMutation` method: ```js todosDux.setMutation( 'addTodo', description => ({next_id: id, todos}) => ({ next_id: 1 + id, todos: [...todos, { description, id, done: false }] })); ``` ## Effects In addition to mutations, Updux also provides action-specific middleware, here called effects. Effects use the usual Redux middleware signature, plus a few goodies. The `getState` and `dispatch` functions are augmented with the dux selectors, and actions, respectively. The selectors and actions are also available from the api object. ```js import u from 'updeep'; import { action, Updux } from 'updux'; // we want to decouple the increment of next_id and the creation of // a new todo. So let's use a new version of the action 'addTodo'. const addTodoWithId = action('addTodoWithId'); const incNextId = action('incNextId'); const addTodo = action('addTodo'); const addTodoEffect = ({ getState, dispatch }) => next => action => { const id = getState.nextId(); dispatch.incNextId(); next(action); dispatch.addTodoWithId({ description: action.payload, id }); } const todosDux = new Updux({ initial: { nextId: 1, todos: [] }, actions: { addTodo, incNextId, addTodoWithId }, selectors: { nextId: ({nextId}) => nextId, }, mutations: { addTodoWithId: (todo) => u({ todos: (todos) => [...todos, todo] }), incNextId: () => u({ nextId: id => id+1 }), }, effects: { 'addTodo': addTodoEffect } }); const store = todosDux.createStore(); store.dispatch.addTodo('Do the thing'); ```