Setting up Redux on a React application.
Tags: webdev, javascript, react, redux
Published: 2023-09-02 17:05:35

# Setting up Redux on a react application.

<aside>
❓ **What is Redux?**

Redux is a state management library that helps you manage the state of your application in a predictable way. It follows the principles of a unidirectional data flow and immutability, making it easier to understand and debug your application's behavior. Redux is not tied to React but is commonly used with it to manage the application's global state.

</aside>

### Installation (On an existing project)

To get started with Redux, you'll need to install both the Redux library and the React bindings for Redux (**`react-redux`**):

```tsx
// On your terminal run
npm install redux react-redux
```

### Project Folder Structure

```tsx
├── src/
│   ├── components/
│   │   ├── UserProfile.js
│   │   └── ...
│   │
│   ├── state/
│   │   ├── actions/
│   │   │   ├── index.js
│   │   │   └── userActions.js
│   │   │   └── cartActions.js
│   │   │   └── ...
│   │   ├── reducers/
│   │   │   ├── index.js
│   │   │   └── userReducer.js
│   │   │   └── cartReducer.js
│   │   │   └── ...
│   │   └── store.js
│   │
│   ├── App.js
│   ├── index.js
│   └── ...
│
├── package.json
├── package-lock.json
├── README.md
└── ...
```

### Reducers

In Redux, reducers specify how your application's state changes in response to actions. Begin by creating individual reducers for different parts of your application's state. Here's an example of two reducers:

```tsx
// src/state/reducers/userReducer.js
const userReducer = (state = {}, action) => {
  switch (action.type) {
    // Handle user-related actions here
    default:
      return state;
  }
};

export default userReducer;
```

```tsx
// src/state/reducers/cartReducer.js

const cartReducer = (state = [], action) => {
  switch (action.type) {
    // Handle shopping cart actions here
    default:
      return state;
  }
};

export default cartReducer;
```

#### Combine Reducers

The setup follows a combined reducers structure to mirror a more realistic production environment with multiple reducers and actions based on sections of your application. To manage these individual reducers in your Redux store, create a root reducer by using Redux's **`combineReducers`** function:

```tsx
// src/state/reducers/index.js

import { combineReducers } from 'redux';
import userReducer from './userReducer';
import cartReducer from './cartReducer';

const rootReducer = combineReducers({
  user: userReducer,
  cart: cartReducer,
  // Add more reducers here if needed
});

export default rootReducer;
```

### Actions

Actions are payloads of information that send data from your application to your store. Define action types and action creators to describe what should happen in your application.

```tsx
// src/state/actions/userActions.js

export const updateUser = (userData) => ({
  type: 'UPDATE_USER',
  payload: userData,
});
```

```tsx
// src/state/actions/cartActions.js

export const addToCart = (item) => ({
  type: 'ADD_TO_CART',
  payload: item,
});
```

### Store

In your **`store.js`** (or equivalent) file, create the Redux store using the combined root reducer and set up Redux DevTools for easier debugging:

```tsx
// src/state/store.js

import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(
  rootReducer,
  window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() // Optional
);

export default store;
```

### Configure the Redux Store and Wrap the Application

In your **`store.js`** (or equivalent) file, create the Redux store using the combined root reducer and set up Redux DevTools for easier debugging:

```tsx
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './state/store'; // Import your Redux store
import App from './App';

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

### Use in your components

Finally you can start using and manipulating the state in your components.

```tsx
// src/components/UserProfile.js

import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { updateUser } from '../redux/actions/userActions'; // Import your Redux action

const UserProfile = () => {
  // Use useSelector to access the user state from Redux
  const user = useSelector((state) => state.user);

  // Use useDispatch to get the dispatch function
  const dispatch = useDispatch();

  const [newName, setNewName] = useState('');

  const handleNameChange = (event) => {
    setNewName(event.target.value);
  };

  const handleUpdateUser = () => {
    // Dispatch the updateUser action to update the user state in Redux
    dispatch(updateUser({ name: newName }));
    setNewName('');
  };

  return (
    <div>
      <h2>User Profile</h2>
      <p>Name: {user.name}</p>
      <div>
        <input
          type="text"
          placeholder="Enter new name"
          value={newName}
          onChange={handleNameChange}
        />
        <button onClick={handleUpdateUser}>Update Name</button>
      </div>
    </div>
  );
};

export default UserProfile;
```