Let's Build our Store using REDUX TOOLKIT

Let's Build our Store using REDUX TOOLKIT

Why Redux Toolkit & not Redux?

We'll just have to install 2 packages @reduxjs/toolkit (Core) & react-redux (Bridge between React & Redux TKT).

Write / Update Slice of Store

Whenever you click an Add To Cart Button => It DISPATCHES an Action => which will call a REDUCER Function => Which Updates the Slice of the Store

Create Store

configureStore comes from @reduxjs/toolkit

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


const appStore = configureStore(
 {
  // reducer of entire store => consists of reducers of all its slices (each slice will have 
its own reducers)
  reducer : {  // App's Store reducer

   cart: cartReducer, // cart slice reducer
   // user: userReducer // user slice reducer
  }
 }
);

export default appStore;

Create A Slice (Cart Slice)

createSlice also comes from @reduxjs/toolkit

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


const cartSlice = createSlice({
 name: 'cart',
 initialState: {
  items: []
 },
 reducers: {
  addItem : (state, action)=>{
   //! We have to Mutate the state here (Directly modifying)
   //! Redux TKT uses IMMER Behind the Scenes
   state.items.push(action.payload);
  },
  removeItem: (state, action) =>{
   state.items.pop();
  },
  clearCart : (state)=>{
   // no need for action payload here as we are just emptying the cart
    console.log(current(state));  // To get Value of state we use current 
                                       (or else it will give Proxy Object)
   state.items.length = 0; // [] - ALWAYS DO THIS WAY ✅ & not state = [] ❌

   return []; // This also works✅ As RTK advises you to Mutate the state directly
                  or return new State
  }
 }
});

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

export default cartSlice.reducer;

1. We export all Actions from here
2. We export Cart Slice's reducer


Menu Items

<{itemCards.map((item)=> 
   <li key={item.card.info.id}>{item.card.info.name} 
        <button onClick={()=>{handleAddToCart(item)}}>Add +</button>
        <button onClick={()=>handleRemoveItem(item)}>Remove -</button></li>)}

useDispatch comes from react-redux

import { useDispatch } from "react-redux";
import { addItem, removeItem } from "../utils/cartSlice";

const dispatch = useDispatch();

const handleAddToCart = (item)=>{
  dispatch(addItem(item));   // action.payload will be equal to this item behind the scenes
 }
 const handleRemoveItem = (item)=>{
  dispatch(removeItem(item));
 }

Provider comes from "react-redux" - This pkg provides A link between React & Redux

import { Provider } from "react-redux";

const AppLayout = () => {
 return (
   <Provider store={appStore}>
     <div className="app">
       <Header />
       <Outlet />
     </div>
   </Provider>
 );
}

Here you want to use Redux Store in your entire App. That's we wrapped over App
You can even use it in A Component only, Just wrap this Provider over it

clearCart Action on Cart Page

import { useDispatch, useSelector } from "react-redux";
import { clearCart } from "../utils/cartSlice";

const Cart = ()=>{
const cartItems = useSelector((store) => store.cart.items); //Subscribed to CartSlice of Store
 const dispatch = useDispatch();

 const handleClearCart = () => {
  dispatch(clearCart());
 }

If You want to Read / Subscribe Data from the Slice of the Store

Suppose you want to show Cart Qty from Cart Slice of the Store in Header

Then Your Header component should be subscribed to that Slice Of the Store using Selector

This useSelector will give you access to the entire Store. You can select the portion/slice of the store eg: Cart

import { useSelector } from "react-redux";

const cartItems = useSelector((store) => store.cart.items); //Subscribing to Cart Slice ✅✅✅

This above variable will only update when the cart items are changed! ✅🔥

If you try to access the entire store ❌

const store = useSelector((store) => store); // Subscribing to the entire store ❌❌❌

This variable will keep on updating everytime when anything from the Store updates ❌

This is very less efficient.Why?
When our Application becomes Big. Our Store size also increases. So any random changes in the store might affect this Component as well. If subscribed to the Entire Store

If something is happening inside some other Slice of the Store. Eg: When user logs In. Then we don't want our Variable inside the Cart to get updated as well.

So We'll Just subscribe to the required smaller portion of the store only, for BETTER PERFORMANCE!!! Tell this to your interviewer ;)

It is useSelector so it means you have to select only a small Portion / Slice of the Store

Extra Info:
Vanilla Redux (older way) didn’t allow us to Mutate the State directly. But with Redux Toolkit WE HAVE TO MUTATE THE STATE.
*
Redux TKT handles everything behind the scenes (making a copy of the state and returning it). It uses Immer Library to do all this. [immerjs.github.io/immer/*](https://immerjs...
We as developers don't have to do it. ❤️‍🔥

Redux Dev Tools

Thank you! Stay tuned for my upcoming blogs 🔥