# React Redux Toolkit

### Introduction

State management in React applications can often become a challenging task, especially as the application grows in complexity. When dealing with numerous components that need to share and manage state, developers require a robust solution to keep everything organized and maintainable. This is where Redux comes into play.

Redux is a popular state management library that helps manage your application's state in a predictable and centralized way. However, setting up Redux can sometimes feel overwhelming, especially for newcomers. Enter Redux Toolkit — a powerful, easy-to-use library that simplifies setting up and using Redux.

React also has a built-in option for state management called the Context API. The Context API is good for simple and small-scale state management needs, but Redux is better for larger and more complex applications where you need a more organized approach.

We'll begin with an overview of Redux architecture, then set up a Redux store using Redux Toolkit, create slices, and connect everything to a React component. By the end of this blog, you'll have a solid foundation for managing state in your React applications with Redux Toolkit and understand how it compares with the Context API.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1720291754967/54eb95fb-e39f-47cd-8e5d-e421cdd545ef.png align="center")

The provided image outlines the basic architecture of a Redux application, showing the flow of data between different components. Here's an explanation of each part of the diagram:  

1. Store :
    
    * The store is the central repository that holds the state of the entire application.
        
    * It is created using `createStore` or `configureStore` from Redux Toolkit.
        
    * The store includes the state and the reducers that define how the state changes in response to actions.
        
2. **Reducers**:
    
    * Reducers are pure functions that take the current state and an action as arguments and return a new state.
        
    * They are responsible for updating the state of store based on the action type and payload.
        
    * Reducers are combined and passed to the store when configuring it.
        
3. **useSelector** :
    
    * `useSelector` is a hook provided by React-Redux to extract data from the Redux store state.
        
    * Components use this hook to read specific parts of the state.
        
    * This ensures that components are automatically re-rendered when the selected state changes.
        
4. **Component UI** :
    
    * This represents the React component that renders the UI.
        
    * The component uses `useSelector` to access the current state from the store and `useDispatch` to send actions to the store.
        
5. **Handler Function** :
    
    * This is a function defined within a component to handle user interactions or other events.
        
    * It typically dispatches actions to the Redux store to update the state.
        
6. **useDispatch** :
    
    * `useDispatch` is a hook provided by React-Redux to dispatch actions to the store.
        
    * Components use this hook to send actions that describe what happened, triggering state updates via reducers.
        

### Flow of Data

1. **State Access** : The component uses `useSelector` to subscribe to specific parts of the state stored in the Redux store.
    
2. **User Interaction** : When a user interacts with the UI (e.g., clicks a button), the handler function is invoked.
    
3. **Dispatching Actions** : The handler function uses `useDispatch` to send actions to the Redux store.
    
4. **Reducers** : The store forwards the dispatched action to the appropriate reducer(s).
    
5. **State Update** : The reducer processes the action and returns a new state.
    
6. **Store Update** : The store updates the state based on the new state returned by the reducer.
    
7. **Component Re-render** : Because the component is subscribed to the store via `useSelector`, it automatically re-renders with the new state.
    

This cycle ensures that the state is predictable and manageable, providing a clear flow of data and making it easier to debug and maintain the application.

### Example :

Let's go through a simple example of setting up and using Redux Toolkit in a React application. This example will involve a counter that can be incremented and decremented.

### Step 1: Install Dependencies

First, install the necessary packages:

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

### Step 2: Set Up the Redux Store

Create a file to configure the store.

#### `src/app/store.js`

```javascript
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';

export const store = configureStore({
  reducer: {
    counter: counterReducer
  }
});
```

### Step 3: Create a Redux Slice

Create a slice for the counter feature.

#### `src/features/counter/counterSlice.js`

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

export const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: state => { state.value += 1 },
    decrement: state => { state.value -= 1 }
  }
});

export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
```

### Step 4: Provide the Store to the React Application

Wrap your application with the Redux Provider and pass the store.

#### `src/index.js`

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';

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

### Step 5: Create a Counter Component

Connect your components to the Redux store using `useSelector` to read state and `useDispatch` to dispatch actions.

#### `src/features/counter/Counter.js`

```javascript
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';

const Counter = () => {
  const count = useSelector(state => state.counter.value);
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Counter: {count}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
};

export default Counter;
```

### Step 6: Use the Counter Component in the App

Include the Counter component in your main application component.

#### `src/App.js`

```javascript
import React from 'react';
import Counter from './features/counter/Counter';

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

export default App;
```

Complete File Structure

```javascript
src/
├── app/
│   └── store.js
├── features/
│   └── counter/
│       ├── counterSlice.js
│       └── Counter.js
├── App.js
└── index.js
```

### Comparison :

Context Api || Redux

1. **Complexity and Setup**:
    
    * **Context API**: Easier to set up and more straightforward for small applications. Suitable for simple state management where state changes are not too frequent.
        
    * **Redux**: Requires more setup initially but provides a more structured approach to state management. Ideal for larger applications with complex state management needs.
        
2. **State Management**:
    
    * **Context API**: Works well for local state or a few global states. However, it can become cumbersome when the state grows and needs to be managed across many components.
        
    * **Redux**: Centralizes state management in a single store, making it easier to manage complex state logic and access state across many components.
        
3. **Performance**:
    
    * **Context API**: Can cause unnecessary re-renders if not optimized, as the whole tree under the provider will re-render on state changes.
        
    * **Redux**: Updates state more precisely, which can improve performance in larger apps.
        
4. **Tooling and Middleware**:
    
    * **Context API**: Limited to what React offers. Extra features like async operations need custom solutions.
        
    * **Redux**: Includes powerful tools like Redux DevTools for debugging and middleware for handling side effects (e.g., async actions with Redux Thunk).
        

For simple applications, the Context API is often enough and easier to use. But as the application gets more complex, Redux (especially with Redux Toolkit) becomes more useful, offering a more scalable, maintainable, and efficient state management solution.
