Skip to content

Latest commit

 

History

History
167 lines (121 loc) · 7.69 KB

redux-flow.md

File metadata and controls

167 lines (121 loc) · 7.69 KB

Why Use Redux?

Redux is a state management library that helps manage and centralize the state of an application. In a React application, especially as it grows larger, passing data through multiple levels of components (prop drilling) can become complex and hard to maintain. Redux addresses this by providing a global state that any component can access, without having to pass data through props.

In this cart feature, you are using Redux to manage the cart state, which allows you to:

  1. Centralize the cart data: The cart's state is stored in one place (the Redux store), making it easy to access and modify it from any component, regardless of its position in the component tree.
  2. Decouple state logic from UI components: The components don’t directly manage the cart data; they interact with Redux actions, which handle the state changes. This makes the code more modular, maintainable, and easier to debug.
  3. Global state access: With Redux, you can access and update the cart’s state from any part of the application, even across different pages, without needing to pass down props manually through components.

Now, let’s go into the specifics of your implementation.


1. Cart Slice (cartSlice.jsx)

nokk is it necessary to have a small amount of toxicity in a relationship to spice up things/or have fun? In this file, you define the Redux slice using createSlice from @reduxjs/toolkit. This slice contains:

  • The cart state (initialState): The state here is an object with one key, items, which is an array that will hold all the items in the cart.
  • Reducers: These are functions that modify the state based on specific actions. In your case, there are three reducers:
    • addItem: This reducer adds a new item to the items array using push. Each time this action is dispatched (i.e., when a user adds an item to the cart), the state is updated to include the new item.
    • removeItem: This reducer removes the last item from the cart using the pop() method.
    • clearCart: This reducer clears all items in the cart by setting the length of the items array to 0.

Why Redux here?

  • You want to maintain a global state for the cart that can be accessed and updated consistently throughout the app. Redux allows you to handle the cart state in one centralized location, making it easy to manipulate.
const cartSlice = createSlice({
  name: "cart",
  initialState: {
    items: [],
  },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload); // Adds a new item to the cart
    },
    removeItem: (state) => {
      state.items.pop(); // Removes the last item
    },
    clearCart: (state) => {
      state.items.length = 0; // Clears the cart
    },
  },
});

2. Store Configuration (appStore.jsx)

In this file, you're configuring the Redux store using configureStore from @reduxjs/toolkit:

  • The cartReducer is added as a part of the store configuration, which handles the cart state. This enables the rest of your app to interact with the cart state using Redux.
  • The store is the central place where the app’s state is stored, and you provide this store to your app using the <Provider> component from React-Redux.

Why Redux here?

  • The store is the global state container for the app. By defining the cart reducer in the store, you ensure that the cart data is globally available, regardless of where it’s needed.
  • It also allows easy integration with the useSelector and useDispatch hooks in your components to interact with the cart state.
const appStore = configureStore({
  reducer: {
    cart: cartReducer, // The cart slice is responsible for managing the cart state
  },
});

3. Cart Component (Cart.jsx)

In this component, you interact with the Redux store to display and update the cart.

  • useSelector: This hook is used to read the current state of the cart from the Redux store. Specifically, it retrieves the items array from the cart slice of the Redux state.
  • handleClearCart: This function dispatches the clearCart action when the "Clear Cart" button is clicked. It interacts with Redux to modify the global state, clearing all items from the cart.

Why Redux here?

  • The Cart component doesn't need to manage the cart state itself. Instead, it simply reads the state from Redux and dispatches actions to update it.
  • By using useSelector, you can dynamically reflect the cart’s contents in the UI, and by dispatching clearCart, you can update the cart from any component in the app.
const Cart = () => {
  const cartItems = useSelector((store) => store.cart.items); // Accessing cart items from Redux store
  const dispatch = useDispatch(); // Dispatching actions to modify the cart state

  const handleClearCart = () => {
    dispatch(clearCart()); // Dispatching the clearCart action to empty the cart
  };

  return (
    <div className="text-center m-4 p-4">
      <button onClick={handleClearCart}>Clear Cart</button>
      {cartItems.length === 0 ? (
        <h1>Cart is Empty</h1>
      ) : (
        <ItemList items={cartItems} />
      )}
    </div>
  );
};

4. ItemList Component (ItemList.jsx)

This component is responsible for displaying the list of items in the cart and offering the ability to add items to the cart.

  • handleAddItem: This function dispatches the addItem action to the Redux store when the "Add +" button is clicked. It updates the global cart state by adding the selected item.

Why Redux here?

  • Modularity: The ItemList is only concerned with displaying the items and sending the action to update the cart. It doesn't need to maintain its own local state for the cart.
  • Centralized logic: The logic for modifying the cart (adding items) is centralized in Redux. This allows other components, such as Cart, to read and modify the cart state without worrying about how it’s managed internally.
const ItemList = ({ items }) => {
  const dispatch = useDispatch(); // Dispatch actions to update the cart state

  const handleAddItem = (item) => {
    dispatch(addItem(item)); // Dispatch the addItem action to add the item to the cart
  };

  return (
    <div>
      {items.map((item) => (
        <div key={item.card.info.id}>
          <button onClick={() => handleAddItem(item)}>Add +</button>
        </div>
      ))}
    </div>
  );
};

Redux Workflow Recap:

  1. Adding Items:

    • The user clicks "Add +" in ItemList.jsx.
    • handleAddItem dispatches the addItem action, updating the cart’s state in the Redux store.
    • The Cart.jsx component re-renders, and the newly added item is displayed.
  2. Clearing the Cart:

    • The user clicks "Clear Cart" in Cart.jsx.
    • handleClearCart dispatches the clearCart action, which clears all items from the cart.
    • The cart is empty, and the UI updates accordingly.
  3. Centralized State:

    • The cart.items array is always the source of truth for the cart state.
    • Any component in the app can read from or update this state by using useSelector to access it and useDispatch to send actions.

Benefits of Using Redux Here:

  • Global state management: Redux provides a way to manage and access the cart’s state from any component, making it easy to interact with the cart data across the app.
  • Separation of concerns: Components (like Cart and ItemList) don’t need to worry about how the cart is managed internally. They only interact with the Redux store through actions and selectors.
  • Predictability and consistency: Since the state is managed in one place, Redux makes it easier to track changes to the cart and debug any issues.