# Mastering Redux Toolkit: A Step-by-Step Tutorial for New Developers.

In the world of building large applications, one of the biggest challenges, especially for teams of developers, is managing the state. While the Context API is useful, it has its limits, especially for applications with many features. To address this, several state management tools have been introduced, but Redux has emerged as a leading solution.

It is worth noting that Redux is not part of ReactJS, despite being frequently used together. While Redux solves many problems, it also introduces new challenges. Setting up a Redux store and writing reducers can be a cumbersome and error-prone process that involves a lot of boilerplate code and manual configuration. This is where the Redux Toolkit comes in - the creators of Redux recognized the need for a more opinionated approach to setting up Redux applications, resulting in the development of the Redux Toolkit, which can be thought of as Redux with batteries included.

The Redux Toolkit eliminates the need for additional libraries and configurations, speeding up the workflow significantly. With the Redux Toolkit, users can benefit from Redux without having to deal with manual setups.

This article will cover all the essential building blocks of the Redux Toolkit. Specifically, we will be developing a shopping cart application that allows users to add and remove items, displaying the total price of the items in their cart. We will explore many of the features of the Redux Toolkit, including Store, Slice, Reducers, and Action Creators.

### What we will cover

Setting up the Project  
Installing Redux Toolkit  
Creating the Redux Store  
Setup Provider  
Creating the Cart Slice  
Creating the UI Components  
Rendering the App  
Running the App  
Conclusion  

### **Step 1: Setting up the Project**

  
We will start by creating a new React project using Create React App. Open up your terminal and run the following command:

```bash
npx create-react-app shopping-cart
```

Once the project is created, navigate to the project directory:

```bash
cd shopping-cart
```

### **Step 2: Installing Redux Toolkit**

  
Next, we need to install Redux Toolkit. Run the following command in your terminal:

```bash
npm install @reduxjs/toolkit react-redux
```

This will install the latest version of Redux Toolkit and add it to our project dependencies. Redux can be used for any frontend framework and is not specific to react, so in order to connect our Redux with react this is where the `react-redux` comes in.

**Just a side note:** When we install `@reduxjs/toolkit` we actually installed a few libraries which are:

```markdown
- redux (core library, state management)
- immer (which allow us to mutate the state)
- redux-thunk (which will handles the async actions)
- reselect (which will simplifies the reducer functions)
```

All these will make sense if you have worked with Redux, but if you haven't worked with Redux before don't worry I will explain all of those as we go.

As an extra, we also get:

```markdown
- redux devtools
- combine reducers
```

### **Step 3: Creating the Redux Store**

  
You are going to think of the **store** as the entire state of your application.  
Create a new file called `store.js` in the `src` directory and add the following code:

```javascript
import { configureStore } from '@reduxjs/toolkit'; 
import cartReducer from './features/cart/cartSlice';

export default configureStore({ 
    reducer: { 
        cart: cartReducer, 
    }, 
});
```

This code imports the `configureStore` function from Redux Toolkit and our `cartReducer` from a file that we will create in the next step. It then exports the configured Redux store.

### **Step 4: Setup Provider**

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

// import store and provider
import { store } from './store';
import { Provider } from 'react-redux';

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);
```

Next, we import the **store** and **Provider** and then wrap the entire application with the *Provider* and pass the *store* as props.

### **Step 5: Creating the Cart Slice**

I want you to think of **slice** as the features of your application for example increasing and decreasing the number of items in the cart or triggering a modal. The bigger the application the more features we are going to have. And in the **Redux toolkit** land, it is called **slice.**

To setup a slice, a common convention is to create a ***features*** folder, Create a new directory called `features` in the `src` directory, and inside it, create a new directory called `cart`. Inside the `cart` directory, create a new file called `cartSlice.js` and add the following code:

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

export const cartSlice = createSlice({
  name: 'cart',
  initialState: [],
  reducers: {
    addToCart: (state, action) => {
      const index = state.findIndex(item => item.id === action.payload.id);
      if (index !== -1) {
        state[index].quantity += 1;
      } else {
        state.push({ ...action.payload, quantity: 1 });
      }
    },
    removeFromCart: (state, action) => {
      const index = state.findIndex(item => item.id === action.payload);
      if (index !== -1) {
        state.splice(index, 1);
      }
    },
    incrementQuantity: (state, action) => {
      const index = state.findIndex(item => item.id === action.payload);
      if (index !== -1) {
        state[index].quantity += 1;
      }
    },
    decrementQuantity: (state, action) => {
      const index = state.findIndex(item => item.id === action.payload);
      if (index !== -1) {
        state[index].quantity -= 1;
        if (state[index].quantity === 0) {
          state.splice(index, 1);
        }
      }
    },
  },
});

export const { addToCart, removeFromCart, incrementQuantity, decrementQuantity } = cartSlice.actions;

export default cartSlice.reducer;

export const selectCart = state => state.cart;

export const selectCartTotal = state => state.cart.reduce((total, item))
   
```

Let's understand what's happening in the code above.  
The cartSlice.js contains the initial state of an empty array and several reducer functions for adding, removing, and updating items in the cart.

The `addToCart` reducer function checks if the item being added already exists in the cart by checking if its `id` matches any existing items in the cart. If it does, it increments the `quantity` of that item. If not, it adds the new item to the cart with a `quantity` of 1.

The `removeFromCart` reducer function removes an item from the cart by finding the index of the item with the `id` that matches the `payload` of the action being dispatched. If the item is found, it is removed from the cart using the `splice` method.

The `incrementQuantity` reducer function increments the `quantity` of an item in the cart by finding the index of the item with the `id` that matches the `payload` of the action being dispatched and incrementing its `quantity`.

The `decrementQuantity` reducer function decrements the `quantity` of an item in the cart by finding the index of the item with the `id` that matches the `payload` of the action being dispatched and decrementing its `quantity`. If the `quantity` of the item becomes 0, the item is removed from the cart using the `splice` method.

The `cartSlice.actions` object exports the four reducer functions defined in the `reducers` property of the `createSlice` function.

The `selectCart` and `selectCartTotal` functions are selectors that are used to access the `cart` slice of the Redux store and compute the total price of all items in the cart.

Finally, the `export default` statement exports the `cartSlice.reducer` function, which is used to create the Redux store for the shopping cart.

Overall, this code defines the structure and behavior of the shopping cart slice.

### **Step 5: Creating the UI Components**

  
Now that we have our Redux store and `cartSlice` set up, we can start building the UI components for our shopping cart application. In the `src` directory, create a new directory called `components`. Inside the `components` directory, create a new file called `Cart.js` and add the following code:

```javascript
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
  selectCart,
  selectCartTotal,
  addToCart,
  removeFromCart,
  incrementQuantity,
  decrementQuantity,
} from '../features/cart/cartSlice';

const Cart = () => {
  const cart = useSelector(selectCart);
  const total = useSelector(selectCartTotal);
  const dispatch = useDispatch();

  const handleAddToCart = item => {
    dispatch(addToCart(item));
  };

  const handleRemoveFromCart = id => {
    dispatch(removeFromCart(id));
  };

  const handleIncrementQuantity = id => {
    dispatch(incrementQuantity(id));
  };

  const handleDecrementQuantity = id => {
    dispatch(decrementQuantity(id));
  };

  return (
    <div>
      <h2>Shopping Cart</h2>
      {cart.length === 0 ? (
        <p>Your cart is empty.</p>
      ) : (
        <>
          <ul>
            {cart.map(item => (
              <li key={item.id}>
                <div>
                  <span>{item.name}</span>
                  <button onClick={() => handleRemoveFromCart(item.id)}>-</button>
                  <span>{item.quantity}</span>
                  <button onClick={() => handleIncrementQuantity(item.id)}>+</button>
                  <span>${item.price * item.quantity}</span>
                </div>
              </li>
            ))}
          </ul>
          <p>Total: ${total}</p>
        </>
      )}

      <button onClick={() => handleAddToCart({ id: 1, name: 'Item 1', price: 10 })}>Add Item 1 to Cart</button>
      <button onClick={() => handleAddToCart({ id: 2, name: 'Item 2', price: 20 })}>Add Item 2 to Cart</button>
    </div>
  );
};

export default Cart;
```

This code defines a `Cart` the component that uses the `useSelector` and `useDispatch` hooks from React Redux to access the `cart` state and dispatch actions to the Redux store. It also defines several event handlers for adding and removing items from the cart and updating item quantities.

### **Step 6: Rendering the App**

  
Finally, we need to render our `Cart` component in our `App` component. Open up the `App.js` file in the `src` directory and replace the existing code with the following:

```javascript
import React from 'react';
import './App.css';
import Cart from './components/Cart';

function App() {
  return (
    <div className="App">
      <Cart />
    </div>
  );
}

export default App;
```

This code simply renders our `Cart` component in the `App` component.

### **Step 7: Running the App**

  
With our project setup and our code written, we can now run our shopping cart application. Open up your terminal and run the following command:

```javascript
npm start
```

This will start the development server and open up the shopping cart application in your browser.  

###   
**Conclusion**

In this article, we learned how to use Redux Toolkit to simplify the process of creating a Redux store and how to build a shopping cart application using React and Redux Toolkit. We created a `cartSlice` that contained the reducer, actions, and selectors
