# Reducers

Reducers apply your actions to the state.

# Initial State

First, you'll need to create an initial state. Some typing might be required here, some can be infered:

import { mapReducers } from "tsrux";

// Some types, you obviously still need
interface TodoEntry {
    id: number;
    label: string;
    checked: boolean;
}

const initialState = {
    list: [] as TodoEntry[],
    nextId: 0,
};

// Some types you can infer from a variable
export type TodoState = typeof initialState;

# Handle Actions

When using mapReducers(), you don't need to define any more types!

  • This function is used to create a reducer for multiple actions.
  • It receives the initial state and a callback.
  • The callback is used to set up action handlers, returns an array of action handlers.
export const todosReducer = mapReducers(initialState, (handle) => [
    // handle(actionCreator, reducer) helps you define a reducer responsible for one single action.
    handle(addTodo, (state, action) => ({ // Both state and action know their types without needing to manually specify them!
        ...state,
        list: [...state.list, { id: state.nextId, label: action.payload.label, checked: false }],
        nextId: state.nextId + 1,
    })),
    handle(setTodoChecked, (state, action) => ({
        ...state,
        list: state.list.map((todo) => {
            if (todo.id === action.payload.id)
                return { ...todo, checked: action.payload.checked };
            return todo;
        })
    })),
    handle(removeTodo, (state, action) => ({
        ...state,
        // Complains about next line: payload does not have an attribute named "ID"
        list: state.list.filter((todo) => todo.id !== action.payload.ID),
    }))
]);