Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

Use of name parameter in createSlice function (Redux Toolkit)


I wanted to understand the use of the name parameter in the createSlice function of the Redux-Toolkit API.

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

const cartSlice = createSlice({
  name: "cartSlice", // Used for internal purposes
  initialState: {
    item: [],
    cost: 0,
  },
  reducers: {
    addItem: (state, action) => {
      state.item.push(action.payload);
      ++state.cost;
    },
    removeItem: (state) => {
      state.item.pop();
      --state.cost;
    },
    clearCart: (state) => {
      state.item.length = 0;
      // state.item.length = [] won't work for some reason
      state.cost = 0;
    },
  },
});

export const { addItem, removeItem, clearCart } = cartSlice.actions;
export default cartSlice.reducer;

From their documentation, name parameter:

A string name for this slice of state. Generated action type constants will use this as a prefix.

Unfortunately, I did not get a clear picture of what's happening even after reading this line. My main confusion stems from the fact that while creating a Store in Redux Toolkit, we do something like this -

import { configureStore } from "@reduxjs/toolkit";
import cartSlice from "./cartSlice";

export default appStore = configureStore({
  reducer: {
    cart: cartSlice,
  },
});

In configureStore function, we are passing an object. From the documentation -

If it is an object of slice reducers, like { users: usersReducer, posts: postsReducer }, configureStore will automatically create the root reducer by passing this object to the Redux combineReducers utility.

Now when using react-redux in my App (React), I am able to access this particular Slice State via what I defined in the configureStore function, which is cart here and not cartSlice. I find this extremely confusing. What is the actual use of the name paramter in the createSlice function then, if not to give the State slice a name for reference in our main code? Is it just used for internal purposes?

I tried to read the documentation but could not understand what's happeneing.


Solution

  • From their documentation, name parameter:

    A string name for this slice of state. Generated action type constants will use this as a prefix.

    Unfortunately, I did not get a clear picture of what's happening even after reading this line.

    It really is much simpler than you are thinking it is. The slice name is only used to name scope the generated actions.

    Given slice:

    const cartSlice = createSlice({
      name: "cartSlice",
      initialState: {
        item: [],
        cost: 0,
      },
      reducers: {
        addItem: (state, action) => {
          state.item.push(action.payload);
          ++state.cost;
        },
        removeItem: (state) => {
          state.item.pop();
          --state.cost;
        },
        clearCart: (state) => {
          state.item = []; // <-- just "reset" back to empty array
          state.cost = 0;
        },
      },
    });
    

    The generated addItem, removeItem, and clearCart actions will have action types "cartSlice/addItem", "cartSlice/removeItem"`` and "cartSlice/clearCart"` respectively. If you enable the Redux-Devtools and install the browser extension, you can actually see these as the dispatched actions to the store along with their payloads and the incremental state updates in the store.

    The name used to identify a reducer function when using the configureStore or combineReducers functions is completely separate and independent of the individual state slice's name property. How you merge the reducers is how you create the state tree, e.g state.cart.item, when selecting from state in the UI components, e.g. const cartItems = useSelector(state => state.cart.item);.