Skip to content

Redux Integration for Cart State ​

This guide explains how Redux Toolkit is used to manage the shopping cart's global state in the Bagisto Headless storefront.

Overview ​

In Bagisto Headless, while the primary source of truth for cart data is the Bagisto GraphQL API, we use Redux Toolkit to manage the client-side state. This ensures that cart updates (like item counts and totals) are instantly reflected across different UI components (Navbar, Cart Sidebar, Product Page) without needing a full page reload or redundant API calls.

Cart State Introduction ​

The cart state acts as a local cache of the user's current shopping session. It stores:

  • Items: List of products added to the cart with their quantities and attributes.
  • Totals: Calculated subtotal, taxes, shipping, and discounts.
  • Checkout Info: Selected addresses, shipping methods, and payment details.

By maintaining this state globally, the storefront can provide a reactive experience, such as updating the cart badge in the header as soon as a user clicks "Add to Cart."

1. Redux Toolkit Setup ​

To get started with Redux in your project, you need to install the core Redux Toolkit package and the React bindings.

bash
# Using npm
npm install @reduxjs/toolkit react-redux

# Using yarn
yarn add @reduxjs/toolkit react-redux

Once installed, these packages allow you to create a logic-driven store using slices, which simplifies state management compared to traditional Redux.

2. Store Configuration ​

The Redux store is configured to hold the cart details, including items, shipping/billing addresses, and selected shipping/payment methods.

File: src/store/store.ts

typescript
import { configureStore } from "@reduxjs/toolkit";
import cartSlice from "./slices/cart-slice";

export const store = configureStore({
  reducer: {
    cartDetail: cartSlice,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

3. Cart Slice ​

The cart-slice defines the structure of the cart state and the reducers used to update it.

File: src/store/slices/cart-slice.ts

typescript
import { createSlice, PayloadAction } from "@reduxjs/toolkit";

const initialState: CartState = {
  cart: undefined,
  selectedShippingRate: null,
  selectedPayment: null,
  billingAddress: null,
  shippingAddress: null,
};

const cartSlice = createSlice({
  name: "cartDetail",
  initialState,
  reducers: {
    addItem: (state, action: PayloadAction<Cart>) => {
      state.cart = { ...action.payload };
    },
    clearCart(state) {
      state.cart = undefined;
      // ... reset other fields
    },
    // ... other reducers like setBillingAddress, setSelectedPayment
  },
});

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

4. Dispatched State Updates ​

The Redux state is updated reactively based on the results of GraphQL mutations. This is typically handled within custom hooks like useAddProduct.

File: src/utils/hooks/useAddToCart.ts

typescript
export const useAddProduct = () => {
  const dispatch = useAppDispatch();

  const { mutateAsync } = useMutation({
    onSuccess: (res) => {
      const responseData = res?.data?.createAddProductInCart?.addProductInCart;
      
      if (responseData?.success) {
        // Update Redux store with the new cart data from API response
        dispatch(addItem(responseData));
        showToast("Product added to cart", "success");
      }
    },
  });
  
  // ...
};

5. Redux Provider ​

To make the store available throughout the application, the Provider from react-redux is included in the global provider wrapper.

File: src/providers/MainProvider.tsx

tsx
export const MainProvider = ({ children }) => {
  return (
    <Provider store={store}>
      {/* Other providers like Apollo, NextAuth */}
      {children}
    </Provider>
  );
};

Summary ​

  • Centralized State: Redux Toolkit manages all cart-related data in a single store.
  • Reactive Updates: State is updated immediately following successful API mutations (addItem, clearCart).
  • UI Consistency: Components like the Cart icon and CartSidebar subscribe to this state for real-time updates.
  • Optimized Flux: Reduces the number of API requests by keeping a local copy of the cart data for immediate UI rendering.

Next Steps ​

Released under the MIT License.