TechnicalPigđŸ·: Redux slice

What is a Redux slice?

When people talk about a “slice” of the Redux store, they are referring to a portion of the overall state managed by Redux.

Given that a Redux store is a single, large object containing the entire state of an application, managing this object can become complex as an application grows. To make state management more manageable, developers often divide the store into smaller parts, each responsible for handling a specific domain or feature of the application. These smaller parts are what we call "slices."

Implementing Slices in Redux

The Redux Toolkit library (@reduxjs/toolkit) provides a function called createSlice which simplifies the process of defining slices.

This function allows you to specify the slice's initial state, reducers, and automatically generates action creators.

Example

Let’s say you have a web app with a menu page. We want to create a “menu” slice that will represent the menu page and all related information, including a “recipe” slice.

The broad steps are:

  1. Define your “slice”

  2. Integrate your “slice” to the Redux store

  3. Dispatch actions to change the state in your store.

1. Define a Slice

We define our menu slice, including the initial state which will contain an array of recipes.

Each recipe might have a structure including an id, name, and description.

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  recipes: [
    { id: 1, name: 'Spaghetti Carbonara', description: 'A classic Italian pasta dish with eggs, cheese, bacon, and black pepper.' },
    { id: 2, name: 'Chicken Curry', description: 'A flavorful curry made with tender chicken pieces, spices, and coconut milk.' },
  ],
  isLoading: false,
  error: null,
};

const menuSlice = createSlice({
  name: 'menu',
  initialState,
  reducers: {
    addRecipe: (state, action) => {
      state.recipes.push(action.payload);
    },
    removeRecipe: (state, action) => {
      state.recipes = state.recipes.filter(recipe => recipe.id !== action.payload.id);
    },
    updateRecipe: (state, action) => {
      const { id, name, description } = action.payload;
      const existingRecipe = state.recipes.find(recipe => recipe.id === id);
      if (existingRecipe) {
        existingRecipe.name = name;
        existingRecipe.description = description;
      }
    },
  },
});

export const { addRecipe, removeRecipe, updateRecipe  } = menuSlice.actions;
export default menuSlice.reducer;

Step 2. Use the Menu Slice in your Store

Integrate the menu slice into your Redux store. If you're using Redux Toolkit's configureStore, it looks something like this:

import { configureStore } from '@reduxjs/toolkit';
import menuReducer from './menuSlice';

export const store = configureStore({
  reducer: {
    menu: menuReducer,
  },
});

Step 3: Dispatch actions to update the “recipes” state in your “Menu” slice

With the store and slice set up, you can now dispatch actions to update the "recipes" state within the menu slice. Here are examples of how to dispatch actions:

// Add recipe

store.dispatch(addRecipe({
  id: 3,
  name: 'Margherita Pizza',
  description: 'A simple pizza with tomatoes, sliced mozzarella, basil, and extra virgin olive oil.'
}));
// Remove recipe by ID

store.dispatch(removeRecipe({ id: 1 }));
// Update recipe

store.dispatch(updateRecipe({
  id: 2,
  name: 'Vegan Chicken Curry',
  description: 'A plant-based curry made with vegan chicken pieces, spices, and coconut milk.'
}));

By dispatching these actions, you can add, remove or update recipes in your menu slice. This structure provides a modular and easy-to-manage approach to handling your app’s state with Redux.

Summary

This approach to organizing the Redux store makes the codebase more modular and easier to manage, especially as the application scales.