React Authentication App Using Redux And Sagas
Tags: react, javascript, redux, saga
Published: 2018-12-15 13:03:38

---
title: React Authentication App Using Redux And Sagas
published: true
description: Authentication using React, Redux and Saga
tags: #react, #javascript, #redux, #saga
---
### Overview
The things that I am going to go through in this post are:
+ [Redux](https://github.com/reduxjs/redux)
+ [Redux-Saga](https://github.com/redux-saga/redux-saga/)

We will be visiting the above-mentioned points while we are working on our Auth app.
Let's establish the fact that Redux is not related to React. Redux can be used in Angular too. Said that, Redux gels with React impeccably. So, let me answer the question what is redux?
To keep it simple Redux is “open-source JavaScript library for managing application state”. It helps you write applications that behave consistently.

To spice this up let’s use real API’s. You can use the backend API service that I have in my repo i.e.., [Authentication with Node](https://github.com/Srivasthava12/Auth-with-Nodejs) and follow the instructions mentioned in README file to run the service or you could use your own json web token based API.

## Let the show begin!!

![Alt Text](https://media.giphy.com/media/oadZJB3hwMFjy/giphy.gif)

To start the show we have to stage our react app. To do so follow the commands.

Make sure you have  `create-react-app`  installed
a) `$ npm install -g create-react-app`

Create react app
b) `$ npx create-react-app my-app`

Move into the directory my-app
c) `$ cd my-app`

Run the react app
d)`$ npm start`

Let's install all the required pacakges 
e)`$ npm i redux react-redux redux-saga react-router redux-form --save`

Now you have staged your react app. So, let's dive in.

In `code` directory. The rundown of the structure is given below:

```
src/  
  login/       
    actions.js
    constants.js
    sagas.js
    selector.js
    reducer.js
    index.js
    components/
             login.js
  register/
    actions.js 	 	
    constants.js
    sagas.js
    selector.js
    reducer.js
    index.js
    components/
             register.js

  user/
    reducer.js
    actions.js
    constants.js

  share/
    Messages.js

  helpers/
    api-errors.js
    check-auth.js

Main.js
index-reducer.js  
index-sagas.js  
```

Let's go throught the folder and files we have just created:
`login/`, `register/` &  `user/`
`login/` & `register/` are  the routes that we are going to use.

Now coming to the files that we created:
a) `actions.js`  are payloads of information that send data from your application to your store. They are plain        Javascript object
b) `reducer.js` specify how the application's state changes in response to sent to the store.
c) `constants.js` the place where we will have our constants for actions and reducers
d)`sagas.js` this is where we manage the impure operations i.e. asynchronous things like data fetching
e) `index-reducer.js` & `index-sagas.js` are the hub where we combile all reducers and sagas

let's go into the code

1) In the directory `src/index`
+ The whole code for `index.js` is:
``` javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { applyMiddleware, createStore, compose } from 'redux';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import { routerMiddleware } from 'react-router-redux';
import { history } from './history';
import { Router } from 'react-router-dom';

// Import all of our components
import App from './App';
import './index.css';

// Import the index reducer and sagas
import IndexReducer from './index-reducer';
import IndexSagas from './index-sagas';

import registerServiceWorker from './registerServiceWorker';

// Setup the middleware to watch between the Reducers and the Actions
const sagaMiddleware = createSagaMiddleware();

const routersMiddleware = routerMiddleware(history);

/*eslint-disable */
const composeSetup =
	process.env.NODE_ENV !== 'production' && typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
		? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
		: compose;
/*eslint-enable */

const store = createStore(
	IndexReducer,
	composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)) // allows redux devtools to watch sagas
);

// Begin our Index Saga
sagaMiddleware.run(IndexSagas);

ReactDOM.render(
	<Provider store={store}>
		<Router history={history}>
			<App />
		</Router>
	</Provider>
	document.getElementById('root')
);
registerServiceWorker();

```
+ Now  let's go throught the above boiler code  
   ``` javascript
   import React from 'react';
  import ReactDOM from 'react-dom';
  import { applyMiddleware, createStore, compose } from 'redux';
  import { Provider } from 'react-redux';
  import createSagaMiddleware from 'redux-saga';
  import { routerMiddleware } from 'react-router-redux';
  import { history } from './history';
  import { Router } from 'react-router-dom';
  
  // Import all of our components
  import App from './App';
  import './index.css';
  
  // Import the index reducer and sagas
  import IndexReducer from './index-reducer';
  import IndexSagas from './index-sagas';
   ```
    import the required pakages
    
+ Middleware
    ```javascript 
    const  sagaMiddleware  =  createSagaMiddleware()
    const  routersMiddleware  =  routerMiddleware(history);
   ```

Creates a Redux middleware and connects the Sagas to the Redux Store
+ Creating a Store
    ```javascript 
    /*eslint-disable */
   const composeSetup = process.env.NODE_ENV !== 'production' && typeof window === 'object' &&
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose
  /*eslint-enable */
  
  const store = createStore(
  IndexReducer,
  composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)),
  )
   ```

 Here ` composeSetup(applyMiddleware(sagaMiddleware, routersMiddleware)),` allows redux to watch sagas and router

+ To Start the Saga middleware 

  ```javascript
  sagaMiddleware.run(IndexSagas)
  ```
Can run  only after the `applyMiddleware` phase.

+ Now let's Render the Index.js
  ``` javascript 
  ReactDOM.render(
    <Provider  store={store}>
      <Router  history={history}>
        <App  />
      </Router>
    </Provider>,
    document.getElementById('root')
  );
  registerServiceWorker();
  ```        
So here we are Providing react app with a store, get it providing store `<Provider  store={store}>`




2) Now let's get into `index-reducer.js`
     ```javascript 
     import { combineReducers } from  'redux'
     import { reducer  as  form } from  'redux-form'

     const  IndexReducer  =  combineReducers({
            form
     })
     export  default  IndexReducer
     ```
  The `combineReducers` helper function turns an object whose values are different reducing functions into a single reducing function you can pass to `createStore`


3) Lets get in to `index-saga.js`
```javascript
import { all } from  'redux-saga/effects';
export  default  function*  IndexSaga() {
yield  all([ ]);
}
```

4) Now that we have done with indexes of the reducers, saga and the main Index lets get in to `App.js` :

```javascript 
import  React, { Component } from  'react';
import  './App.css';
import  Main  from  './Main';
class  App  extends  Component {
  render() {
    return (
      <div  className="App">
        <Main  />
      </div>
    );
  }
}
export  default  App;
```
Here in App,   `<Main />` is where our routes exist 

5) We have separated a component to deal with the routes of the application i.e. the Main Component

``` javascript 
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Login from '../src/login';
import Register from '../src/register';

export default class Main extends React.Component {
	render() {
		return (
			<main>
				<Switch>
					<Route path="/login" component={Login} />
					<Route path="/register" component={Register} />
				</Switch>
			</main>
		);
	}
}
```

Let's dig in, 
`Switch` 
`<Switch>` is unique in that it renders a route exclusively. In contrast, every `<Route>` that matches the location renders inclusively.