Search code examples
reactjstypescriptreduxredux-toolkit

how to use createSlice's RTK function to create a state that has multiple properties?


I am using Redux-Toolkit in a React project to manage the state of my app. I created a slice for customers. A customer is an object that possesses a name, id, list of food, number of guests accompanying them, the location of the restaurant, and the order's date and time.

In createSlice, what code should I write exactly to add all these properties to the state?

I took this project from someone else and initially, the customers' state had only an id, name, and array of food. Now I want to add the other properties as well. Here is the Customer Interface:

export interface Customer {
  id: string;
  name: string;
  food: string[];
}

And here is the code of the customerSlice:

export const customerSlice = createSlice({
  name: "customer",
  initialState,
  reducers: {
    addCustomer: (state, action: PayloadAction<Customer>) => {
      state.value.push(action.payload);
    },
    addFoodToCustomer: (
      state,
      action: PayloadAction<AddFoodToCustomerPayload>
    ) => {
      state.value.forEach((customer) => {
        if (customer.id === action.payload.id) {
          customer.food.push(action.payload.food);
        }
      });
    },
  },
});

How do I add these properties to the state?

guestsNumber: number | string;
restauLocation: string;
orderDate: string;
orderTime: string;

Solution

  • You can add the new fields/properties to the Customer interface.

    export interface Customer {
      id: string;
      name: string;
      food: string[];
      guestsNumber: number | string; // <-- new property
      restauLocation: string;        // <-- new property
      orderDate: string;             // <-- new property
      orderTime: string;             // <-- new property
    }
    

    I also suggest giving the state better property names, e.g. state.customers is much more informative than state.value. The initialState doesn't really need to have anything new since it's just an array of Customer objects. New actions can be created and can access/modify any Customer properties, e.g. the example someNewAction action below.

    Example:

    export interface CustomerState {
      customers: Customer[];
    }
    
    const initialState: CustomerState = {
      customers: [],
    };
    
    export const customerSlice = createSlice({
      name: "customer",
      initialState,
      reducers: {
        addCustomer: (state, action: PayloadAction<Customer>) => {
          state.customers.push(action.payload);
        },
        addFoodToCustomer: (
          state,
          action: PayloadAction<AddFoodToCustomerPayload>
        ) => {
          const { id, food } = action.payload;
    
          const customer = state.customers.find(customer => customer.id === id);
    
          if (customer) {
            customer.food.push(food);
          };
        },
        ...
        someNewAction: (state, action<.....>) => {
          const { id, guestNumber, location, ...etc... } = action.payload;
    
          const customer = state.customers.find(customer => customer.id === id);
    
          if (customer) {
            customer.guestsNumber = guestNumber;
            customer.restauLocation = location;
            ...
          };
        },
      },
    });