Blog>
Snippets

Complex Multi-Model Form State Using createReducer

Demonstrate how to use createReducer to manage a complex state involving multiple models including nested objects and arrays.
import { createAction, createReducer } from '@reduxjs/toolkit';

// Action types to be dispatched
const ADD_USER = 'ADD_USER';
const UPDATE_USER_ADDRESS = 'UPDATE_USER_ADDRESS';
const ADD_ORDER_TO_USER = 'ADD_ORDER_TO_USER';

// Action creators
const addUser = createAction(ADD_USER);
const updateUserAddress = createAction(UPDATE_USER_ADDRESS);
const addOrderToUser = createAction(ADD_ORDER_TO_USER);

const initialState = {
  users: [],
  orders: {}
};

// Reducer
const complexFormReducer = createReducer(initialState, {
  [addUser]: (state, action) => {
    // Add a new user
    state.users.push(action.payload);
  },
  [updateUserAddress]: (state, action) => {
    // Find user and update address
    const user = state.users.find(user => user.id === action.payload.userId);
    if (user) {
      user.address = action.payload.address;
    }
  },
  [addOrderToUser]: (state, action) => {
    // Add order to user and create a relation in the orders object
    const { userId, order } = action.payload;
    const user = state.users.find(user => user.id === userId);
    if (user) {
      state.orders[order.id] = {...order, userId};
      user.orderIds.push(order.id);
    }
  }
});
// In this example, we use `createReducer` from Redux Toolkit to manage a state // with users and their orders. The state structure consists of an array of users, // each with their own details and a list of order IDs. // The orders themselves are stored in an object for quick access by ID. // `addUser` action adds a new user to the state. // `updateUserAddress` action finds a user by ID and updates their address. // `addOrderToUser` action creates a new order, links it to the user, and updates both the users and orders state.