# ReactJS - Redux

React redux is an advanced state management library for React. As we learned earlier, React only supports component level state management. In a big and complex application, large number of components are used. React recommends to move the state to the top level component and pass the state to the nested component using properties. It helps to some extent but it becomes complex when the components increases.

React redux chips in and helps to maintain state at the application level. React redux allows any component to access the state at any time. Also, it allows any component to change the state of the application at any time.

Let us learn about the how to write a React application using React redux in this chapter.

## Concepts

React redux maintains the state of the application in a single place called Redux store. React component can get the latest state from the store as well as change the state at any time. Redux provides a simple process to get and set the current state of the application and involves below concepts.

**Store** − The central place to store the state of the application.

**Actions** − Action is an plain object with the type of the action to be done and the input (called payload) necessary to do the action. For example, action for adding an item in the store contains **ADD\_ITEM** as type and an object with item’s details as payload. The action can be represented as −

```
{ 
   type: 'ADD_ITEM', 
   payload: { name: '..', ... }
}
```

<div class="open_grepper_editor" id="bkmrk-" title="Edit & Save To Grepper">  
</div>***Reducers*** − Reducers are pure functions used to create a new state based on the existing state and the current action. It returns the newly created state. For example, in add item scenario, it creates a new item list and merges the item from the state and new item and returns the newly created list.

***Action creators*** − *Action creator* creates an action with proper action type and data necessary for the action and returns the action. For example, ***addItem*** action creator returns below object −

```
{ 
   type: 'ADD_ITEM', 
   payload: { name: '..', ... }
}
```

<div class="open_grepper_editor" id="bkmrk--0" title="Edit & Save To Grepper">  
</div>**Component** − Component can connect to the store to get the current state and dispatch action to the store so that the store executes the action and updates it’s current state.

The workflow of a typical redux store can be represented as shown below.

![Redux Store](https://www.tutorialspoint.com/reactjs/images/redux_store.jpg)

- React component subscribes to the store and get the latest state during initialization of the application.
- To change the state, React component creates necessary action and dispatches the action.
- Reducer creates a new state based on the action and returns it. Store updates itself with the new state.
- Once the state changes, store sends the updated state to all its subscribed component.

## Redux API

Redux provides a single api, *connect* which will connect a components to the store and allows the component to get and set the state of the store.

The signature of the connect API is −

```
function connect(mapStateToProps?, mapDispatchToProps?, mergeProps?, options?)
```

<div class="open_grepper_editor" id="bkmrk--2" title="Edit & Save To Grepper">  
</div>All parameters are optional and it returns a HOC (higher order component). A higher order component is a function which wraps a component and returns a new component.

```
let hoc = connect(mapStateToProps, mapDispatchToProps) 
let connectedComponent = hoc(component)
```

<div class="open_grepper_editor" id="bkmrk--3" title="Edit & Save To Grepper">  
</div>Let us see the first two parameters which will be enough for most cases.

- **mapStateToProps** − Accepts a function with below signature.

```
(state, ownProps?) => Object
```

<div class="open_grepper_editor" id="bkmrk--4" title="Edit & Save To Grepper">  
</div>Here, **state** refers current state of the store and **Object** refers the new props of the component. It gets called whenever the state of the store is updated.

```
(state) => { prop1: this.state.anyvalue }
```

<div class="open_grepper_editor" id="bkmrk--5" title="Edit & Save To Grepper">  
</div>- ***mapDispatchToProps*** − Accepts a function with below signature.

```
Object | (dispatch, ownProps?) => Object
```

<div class="open_grepper_editor" id="bkmrk--6" title="Edit & Save To Grepper">  
</div>Here, **dispatch** refers the dispatch object used to dispatch action in the redux store and **Object** refers one or more dispatch functions as props of the component.

```
(dispatch) => {
   addDispatcher: (dispatch) => dispatch({ type: 'ADD_ITEM', payload: { } }),
   removeispatcher: (dispatch) => dispatch({ type: 'REMOVE_ITEM', payload: { } }),
}
```

<div class="open_grepper_editor" id="bkmrk--7" title="Edit & Save To Grepper">  
</div>## Provider component

React Redux provides a Provider component and its sole purpose to make the Redux store available to its all nested components connected to store using connect API. The sample code is given below −

```
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { App } from './App'
import createStore from './createReduxStore'

const store = createStore()

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

<div class="open_grepper_editor" id="bkmrk--8" title="Edit & Save To Grepper">  
</div>Now, all the component inside the App component can get access to the Redux store by using connect API.

### Working example

Let us recreate our expense manager application and uses the React redux concept to maintain the state of the application.

First, create a new react application, *react-message-app* using Create *React App* or *Rollup* bundler by following instruction in Creating a React application chapter.

Next, install Redux and React redux library.

```
npm install redux react-redux --save
```

<div class="open_grepper_editor" id="bkmrk--9" title="Edit & Save To Grepper">  
</div>Next, install uuid library to generate unique identifier for new expenses.

```
npm install uuid --save
```

<div class="open_grepper_editor" id="bkmrk--10" title="Edit & Save To Grepper">  
</div>Next, open the application in your favorite editor.

Next, create *src* folder under the root directory of the application.

Next, create *actions* folder under *src* folder.

Next, create a file, *types.js* under *src/actions* folder and start editing.

Next, add two action type, one for add expense and one for remove expense.

```
export const ADD_EXPENSE = 'ADD_EXPENSE'; 
export const DELETE_EXPENSE = 'DELETE_EXPENSE';
```

<div class="open_grepper_editor" id="bkmrk--11" title="Edit & Save To Grepper">  
</div>Next, create a file, *index.js* under *src/actions* folder to add action and start editing.

Next, import **uuid** to create unique identifier.

```
import { v4 as uuidv4 } from 'uuid';
```

<div class="open_grepper_editor" id="bkmrk--12" title="Edit & Save To Grepper">  
</div>Next, import action types.

```
import { ADD_EXPENSE, DELETE_EXPENSE } from './types';
```

<div class="open_grepper_editor" id="bkmrk--13" title="Edit & Save To Grepper">  
</div>Next, add a new function to return action type for adding an expense and export it.

```
export const addExpense = ({ name, amount, spendDate, category }) => ({
   type: ADD_EXPENSE,
   payload: {
      id: uuidv4(),
      name,
      amount,
      spendDate,
      category
   }
});
```

<div class="open_grepper_editor" id="bkmrk--14" title="Edit & Save To Grepper">  
</div>Here, the function expects expense object and return action type of **ADD\_EXPENSE** along with a payload of expense information.

Next, add a new function to return action type for deleting an expense and export it.

```
export const deleteExpense = id => ({
   type: DELETE_EXPENSE,
   payload: {
      id
   }
});
```

<div class="open_grepper_editor" id="bkmrk--15" title="Edit & Save To Grepper">  
</div>Here, the function expects id of the expense item to be deleted and return action type of ‘DELETE\_EXPENSE’ along with a payload of expense id.

The complete source code of the action is given below −

```
import { v4 as uuidv4 } from 'uuid';
import { ADD_EXPENSE, DELETE_EXPENSE } from './types';

export const addExpense = ({ name, amount, spendDate, category }) => ({
   type: ADD_EXPENSE,
   payload: {
      id: uuidv4(),
      name,
      amount,
      spendDate,
      category
   }
});
export const deleteExpense = id => ({
   type: DELETE_EXPENSE,
   payload: {
      id
   }
});
```

<div class="open_grepper_editor" id="bkmrk--16" title="Edit & Save To Grepper">  
</div>Next, create a new folder, reducers under *src* folder.

Next, create a file, *index.js* under *src/reducers* to write reducer function and start editing.

Next, import the action types.

```
import { ADD_EXPENSE, DELETE_EXPENSE } from '../actions/types';
```

<div class="open_grepper_editor" id="bkmrk--17" title="Edit & Save To Grepper">  
</div>Next, add a function, *expensesReducer* to do the actual feature of adding and updating expenses in the redux store.

```
export default function expensesReducer(state = [], action) {
   switch (action.type) {
      case ADD_EXPENSE:
         return [...state, action.payload];
      case DELETE_EXPENSE:
         return state.filter(expense => expense.id !== action.payload.id);
      default:
         return state;
   }
}
```

<div class="open_grepper_editor" id="bkmrk--18" title="Edit & Save To Grepper">  
</div>The complete source code of the reducer is given below −

```
import { ADD_EXPENSE, DELETE_EXPENSE } from '../actions/types';

export default function expensesReducer(state = [], action) {
   switch (action.type) {
      case ADD_EXPENSE:
         return [...state, action.payload];
      case DELETE_EXPENSE:
         return state.filter(expense => expense.id !== action.payload.id);
      default:
         return state;
   }
}
```

<div class="open_grepper_editor" id="bkmrk--19" title="Edit & Save To Grepper">  
</div>Here, the reducer checks the action type and execute the relevant code.

Next, create *components* folder under *src* folder.

Next, create a file, *ExpenseEntryItemList.css* under *src/components* folder and add generic style for the html tables.

```
html {
   font-family: sans-serif;
}
table {
   border-collapse: collapse;
   border: 2px solid rgb(200,200,200);
   letter-spacing: 1px;
   font-size: 0.8rem;
}
td, th {
   border: 1px solid rgb(190,190,190);
   padding: 10px 20px;
}
th {
   background-color: rgb(235,235,235);
}
td, th {
   text-align: left;
}
tr:nth-child(even) td {
   background-color: rgb(250,250,250);
}
tr:nth-child(odd) td {
   background-color: rgb(245,245,245);
}
caption {
   padding: 10px;
}
tr.highlight td { 
   background-color: #a6a8bd;
}
```

<div class="open_grepper_editor" id="bkmrk--20" title="Edit & Save To Grepper">  
</div>Next, create a file, *ExpenseEntryItemList.js* under *src/components* folder and start editing.

Next, import React and React redux library.

```
import React from 'react'; 
import { connect } from 'react-redux';
```

<div class="open_grepper_editor" id="bkmrk--21" title="Edit & Save To Grepper">  
</div>Next, import ExpenseEntryItemList.css file.

```
import './ExpenseEntryItemList.css';
```

<div class="open_grepper_editor" id="bkmrk--22" title="Edit & Save To Grepper">  
</div>Next, import action creators.

```
import { deleteExpense } from '../actions'; 
import { addExpense } from '../actions';
```

<div class="open_grepper_editor" id="bkmrk--23" title="Edit & Save To Grepper">  
</div>Next, create a class, ExpenseEntryItemList and call constructor with **props**.

```
class ExpenseEntryItemList extends React.Component {
   constructor(props) {
      super(props);
   }
}
```

<div class="open_grepper_editor" id="bkmrk--24" title="Edit & Save To Grepper">  
</div>Next, create **mapStateToProps** function.

```
const mapStateToProps = state => {
   return {
      expenses: state
   };
};
```

<div class="open_grepper_editor" id="bkmrk--25" title="Edit & Save To Grepper">  
</div>Here, we copied the input state to **expenses** props of the component.

Next, create **mapDispatchToProps** function.

```
const mapDispatchToProps = dispatch => {
   return {
      onAddExpense: expense => {
         dispatch(addExpense(expense));
      },
      onDelete: id => {
         dispatch(deleteExpense(id));
      }
   };
};
```

<div class="open_grepper_editor" id="bkmrk--26" title="Edit & Save To Grepper">  
</div>Here, we created two function, one to dispatch add expense **(addExpense)** function and another to dispatch delete expense **(deleteExpense)** function and mapped those function to props of the component.

Next, export the component using **connect** api.

```
export default connect(
   mapStateToProps,
   mapDispatchToProps
)(ExpenseEntryItemList);
```

<div class="open_grepper_editor" id="bkmrk--27" title="Edit & Save To Grepper">  
</div>Now, the component gets three new properties given below −

- expenses − list of expense
- onAddExpense − function to dispatch **addExpense** function
- onDelete − function to dispatch **deleteExpense** function

Next, add few expense into the redux store in the constructor using **onAddExpense** property.

```
if (this.props.expenses.length == 0)
{
   const items = [
      { id: 1, name: "Pizza", amount: 80, spendDate: "2020-10-10", category: "Food" },
      { id: 2, name: "Grape Juice", amount: 30, spendDate: "2020-10-12", category: "Food" },
      { id: 3, name: "Cinema", amount: 210, spendDate: "2020-10-16", category: "Entertainment" },
      { id: 4, name: "Java Programming book", amount: 242, spendDate: "2020-10-15", category: "Academic" },
      { id: 5, name: "Mango Juice", amount: 35, spendDate: "2020-10-16", category: "Food" },
      { id: 6, name: "Dress", amount: 2000, spendDate: "2020-10-25", category: "Cloth" },
      { id: 7, name: "Tour", amount: 2555, spendDate: "2020-10-29", category: "Entertainment" },
      { id: 8, name: "Meals", amount: 300, spendDate: "2020-10-30", category: "Food" },
      { id: 9, name: "Mobile", amount: 3500, spendDate: "2020-11-02", category: "Gadgets" },
      { id: 10, name: "Exam Fees", amount: 1245, spendDate: "2020-11-04", category: "Academic" }
   ]
   items.forEach((item) => {
      this.props.onAddExpense(
         { 
            name: item.name, 
            amount: item.amount, 
            spendDate: item.spendDate, 
            category: item.category 
         }
      );
   })
}
```

<div class="open_grepper_editor" id="bkmrk--28" title="Edit & Save To Grepper">  
</div>Next, add an event handler to delete the expense item using expense id.

```
handleDelete = (id,e) => {
   e.preventDefault();
   this.props.onDelete(id);
}
```

<div class="open_grepper_editor" id="bkmrk--29" title="Edit & Save To Grepper">  
</div>Here, the event handler calls the **onDelete** dispatcher, which call **deleteExpense** along with the expense id.

Next, add a method to calculate the total amount of all expenses.

```
getTotal() {
   let total = 0;
   for (var i = 0; i < this.props.expenses.length; i++) {
      total += this.props.expenses[i].amount
   }
   return total;
}
```

<div class="open_grepper_editor" id="bkmrk--30" title="Edit & Save To Grepper">  
</div>Next, add *render()* method and list the expense item in the tabular format.

```
render() {
   const lists = this.props.expenses.map(
      (item) =>
      <tr key={item.id}>
         <td>{item.name}</td>
         <td>{item.amount}</td>
         <td>{new Date(item.spendDate).toDateString()}</td>
         <td>{item.category}</td>
         <td><a href="#"
            onClick={(e) => this.handleDelete(item.id, e)}>Remove</a></td>
      </tr>
   );
   return (
      <div>
         <table>
            <thead>
               <tr>
                  <th>Item</th>
                  <th>Amount</th>
                  <th>Date</th>
                  <th>Category</th>
                  <th>Remove</th>
               </tr>
            </thead>
            <tbody>
               {lists}
               <tr>
                  <td colSpan="1" style={{ textAlign: "right" }}>Total Amount</td>
                  <td colSpan="4" style={{ textAlign: "left" }}>
                     {this.getTotal()}
                  </td>
               </tr>
            </tbody>
         </table>
      </div>
   );
}
```

<div class="open_grepper_editor" id="bkmrk--31" title="Edit & Save To Grepper">  
</div>Here, we set the event handler *handleDelete* to remove the expense from the store.

The complete source code of the *ExpenseEntryItemList* component is given below −

```
import React from 'react';
import { connect } from 'react-redux';
import './ExpenseEntryItemList.css';
import { deleteExpense } from '../actions';
import { addExpense } from '../actions';

class ExpenseEntryItemList extends React.Component {
   constructor(props) {
      super(props);

      if (this.props.expenses.length == 0){
         const items = [
            { id: 1, name: "Pizza", amount: 80, spendDate: "2020-10-10", category: "Food" },
            { id: 2, name: "Grape Juice", amount: 30, spendDate: "2020-10-12", category: "Food" },
            { id: 3, name: "Cinema", amount: 210, spendDate: "2020-10-16", category: "Entertainment" },
            { id: 4, name: "Java Programming book", amount: 242, spendDate: "2020-10-15", category: "Academic" },
            { id: 5, name: "Mango Juice", amount: 35, spendDate: "2020-10-16", category: "Food" },
            { id: 6, name: "Dress", amount: 2000, spendDate: "2020-10-25", category: "Cloth" },
            { id: 7, name: "Tour", amount: 2555, spendDate: "2020-10-29", category: "Entertainment" },
            { id: 8, name: "Meals", amount: 300, spendDate: "2020-10-30", category: "Food" },
            { id: 9, name: "Mobile", amount: 3500, spendDate: "2020-11-02", category: "Gadgets" },
            { id: 10, name: "Exam Fees", amount: 1245, spendDate: "2020-11-04", category: "Academic" }
         ]
         items.forEach((item) => {
            this.props.onAddExpense(
               { 
                  name: item.name, 
                  amount: item.amount, 
                  spendDate: item.spendDate, 
                  category: item.category 
               }
            );
         })
      }
   }
   handleDelete = (id,e) => {
      e.preventDefault();
      this.props.onDelete(id);
   }
   getTotal() {
      let total = 0;
      for (var i = 0; i < this.props.expenses.length; i++) {
         total += this.props.expenses[i].amount
      }
      return total;
   }
   render() {
      const lists = this.props.expenses.map((item) =>
         <tr key={item.id}>
            <td>{item.name}</td>
            <td>{item.amount}</td>
            <td>{new Date(item.spendDate).toDateString()}</td>
            <td>{item.category}</td>
            <td><a href="#"
               onClick={(e) => this.handleDelete(item.id, e)}>Remove</a></td>
         </tr>
      );
      return (
         <div>
            <table>
               <thead>
                  <tr>
                     <th>Item</th>
                     <th>Amount</th>
                     <th>Date</th>
                     <th>Category</th>
                     <th>Remove</th>
                  </tr>
               </thead>
               <tbody>
                  {lists}
                  <tr>
                     <td colSpan="1" style={{ textAlign: "right" }}>Total Amount</td>
                     <td colSpan="4" style={{ textAlign: "left" }}>
                        {this.getTotal()}
                     </td>
                  </tr>
               </tbody>
            </table>
         </div>
      );
   }
}
const mapStateToProps = state => {
   return {
      expenses: state
   };
};
const mapDispatchToProps = dispatch => {
   return {
      onAddExpense: expense => {
         dispatch(addExpense(expense));
      },
      onDelete: id => {
         dispatch(deleteExpense(id));
      }
   };
};
export default connect(
   mapStateToProps,
   mapDispatchToProps
)(ExpenseEntryItemList);
```

<div class="open_grepper_editor" id="bkmrk--32" title="Edit & Save To Grepper">  
</div>Next, create a file, *App.js* under the *src/components* folder and use *ExpenseEntryItemList* component.

```
import React, { Component } from 'react';
import ExpenseEntryItemList from './ExpenseEntryItemList';

class App extends Component {
   render() {
      return (
         <div>
            <ExpenseEntryItemList />
         </div>
      );
   }
}
export default App;
```

<div class="open_grepper_editor" id="bkmrk--33" title="Edit & Save To Grepper">  
</div>Next, create a file, *index.js* under src folder.

```
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provider } from 'react-redux';
import rootReducer from './reducers';
import App from './components/App';

const store = createStore(rootReducer);

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

<div class="open_grepper_editor" id="bkmrk--34" title="Edit & Save To Grepper">  
</div>Here,

- Create a store using **createStore** by attaching the our reducer.
- Used Provider component from React redux library and set the store as props, which enables all the nested component to ***connect*** to store using connect api.

Finally, create a *public* folder under the root folder and create *index.html* file.

```

<html lang="en">
   <head>
      <meta charset="utf-8">
      <title>React Containment App</title>
   </head>
   <body>
      <div id="root"></div>
      <script type="text/JavaScript" src="./index.js"></script>
   </body>
</html>
```

<div class="open_grepper_editor" id="bkmrk--35" title="Edit & Save To Grepper">  
</div>Next, serve the application using npm command.

```
npm start
```

<div class="open_grepper_editor" id="bkmrk--36" title="Edit & Save To Grepper">  
</div>Next, open the browser and enter *http://localhost:3000* in the address bar and press enter.

Clicking the remove link will remove the item from redux store.

![Redux](https://www.tutorialspoint.com/reactjs/images/redux.jpg)

</body></html>