> For the complete documentation index, see [llms.txt](https://tkssharma.gitbook.io/react-training/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tkssharma.gitbook.io/react-training/react-redux-day-09/redux-state-manager.md).

# Redux State Manager

## Building Blocks Of Redux <a href="#d9bf" id="d9bf"></a>

To fully understand the Redux concept we first need to take a look at the man building block. Redux has three main parts: Actions, Reducers and Store. Let’s explore what each one does:

## Actions <a href="#id-1d95" id="id-1d95"></a>

Actions are used to send information from the application to the store. Sending information to the store is needed to change the application state after a user interaction, internal events or API calls. \
\
Actions are JavaScript objects as you can see in the following example:

```
{
    type: LOGIN_USER,
    payload: {username: ‘sebastian’, password: ‘123456’}
}
```

Here the action object has two properties:

* *type*: a constant to identify the type of action
* *payload*: the object which is assigned to this property contains the data which are sent to the store

Action objects are created by using functions. These functions are called action creators:

```
function authUser(data) {
    return {
        type: LOGIN_USER,
        payload: data
    }
}
```

Here you can see that the only purpose of an action creator function is to return the action object as described.\
\
Calling actions in the application is easy by using the *dispatch* method:\
\
`dispatch(authUser(data));`

## Reducers <a href="#id-1712" id="id-1712"></a>

Reducers are the most important building block and it’s important to understand the concept. Reducers are pure JavaScript functions that take the current application state and an action object and return a new application state:

```
function myReducer (state , action)  {
  switch (action.type) {
    case 'LOGIN_USER':
      return Object.assign({}, state, {
        auth: action.payload
      })
    default:
      return state
  }
}
```

The important thing to notice here is that the state is not changed directly. Instead a new state object (based on the old state) is created and the update is done to the new state.

## Store <a href="#a952" id="a952"></a>

The store is the central objects that holds the state of the application. The store is created by using the *createStore* method from the Redux library:

```
import { createStore } from ‘redux’;
let store = createStore(myReducer);
```

You need to pass in the reducer function as a parameter. Now you’re ready to disptach a action to the store which is handled by the reducer:

```
let authData = {username: ‘sebastian’, password: ‘123456’};
store.dispatch(authUser(authData));
```

The following figure shows the data flow between the building blocks:![](https://miro.medium.com/max/60/1*fcbWaGi9QCNYa5DoUYmERw.png?q=20)

![](https://miro.medium.com/max/1400/1*fcbWaGi9QCNYa5DoUYmERw.png)

## Building A Sample React-Redux Application <a href="#cfef" id="cfef"></a>

## What We’Re Going To Build <a href="#d22e" id="d22e"></a>

Now let’s continue with the pratical part of this tutorial and start building a real-world React-Redux application from scratch. In the following screenshot you can see what we’re going to build:

![](https://miro.medium.com/max/1400/1*bUP-9ECqRL-psBnC7DmuhA.png)

The application is giving the user the option to vote for his favorite front-end framework by clicking on the logos. The vote count is stored in the application store and updated every time the user votes. \
\
The voting result is displayed below by a separate React component. The component accesses to store to get the current voting values for each framework. \
\
Let’s get started!

## Setting Up The React Project <a href="#id-296a" id="id-296a"></a>

First we need to setup a new React project. The easiest way to do so is to use *create-react-app*:\
\
`$ create-react-app my-redux-app`\
\
Enter the newly created directory *my-redux-app* and start the development web server:\
\
`$ cd my-redux-app`\
`$ yarn start`\
\
Finally we need to make sure that Redux is added to our project:\
\
`$ yarn add redux`

## Implementing Actions <a href="#id-2b86" id="id-2b86"></a>

Let’s start the implementation by creating a new file *index.js* in folder *src/actions*. This file contains the action creator functions which are needed in our application:

```
export const voteAngular = () => {
  return {
    type: 'VOTE_ANGULAR'
  }
}export const voteReact = () => {
  return {
    type: 'VOTE_REACT'
  }
}export const voteVuejs = () => {
  return {
    type: 'VOTE_VUEJS'
  }
}
```

The user is able to choose from the list of three front-end frameworks: Angular, React, Vue.js. We’re defining three corresponding action creators here. The action object which is created in all three cases is just containing the type property with one of the following types:

* VOTE\_ANGULAR
* VOTE\_REACT
* VOTE\_VUEJS

Using a payload object is not necessary in this case because we do not need to pass data to the store. We only need the information that a user has voted to increment the vote counter in the store accordingly.

## Implementing Reducers <a href="#id-2d31" id="id-2d31"></a>

Next, let’s implement the Reducer function. Create a new folder *src/reducers*and within that folder create the new file *index.js* and insert the following code:

```
const initialState = {
  angular: 0,
  react: 0,
  vuejs: 0
}export default (state = initialState, action) => {
  switch (action.type) {
    case 'VOTE_ANGULAR':
      console.log("Your choice is Angular!")
      return Object.assign({}, state, {
        angular: state.angular + 1
      })
    case 'VOTE_REACT':
      console.log("Your choice is React!")
      return Object.assign({}, state, {
        react: state.react + 1
      })
    case 'VOTE_VUEJS':
      console.log("Your choice is Vue.js")
      return Object.assign({}, state, {
        vuejs: state.vuejs + 1
      })
    default:
      return state
  }
}
```

First we’re defining a const object which contains the initial state of our application. The state object consists of three properties *angular*, *react* and *vuejs*. Initially the values of these properties are set to 0.\
\
To set the initial state we need to assign the *initialState* object to the first parameter state of the reducer function as a default value. \
\
The Reducer function contains a switch statement which handles three cases:

* VOTE\_ANGULAR: If an action of type VOTE\_ANGULAR has been dispatched to the store a new state object is created and the state property *angular* is being incremented.
* VOTE\_REACT: If an action of type VOTE\_REACT has been dispatched to the store a new state object is created and the state property *react* is being incremented.
* VOTE\_VUEJS: If an action of type VOTE\_VUEJS has been dispatched to the store a new state object is created and the state property *vuejs* is being incremented.

In each case the Object.assign method is used to create a new state object.

## Creating The Store <a href="#id-25fd" id="id-25fd"></a>

To complete the Redux parts of our applications, let’s create the store in file *index.js*:

```
import { createStore } from 'redux';
import myApp from './reducers';let store = createStore(myApp);function render() {
  ReactDOM.render(
    [...]
  );
}store.subscribe(render);render();
```

First we’re making sure that *createStore* is imported. Furthermore we’re importing the Reducer. Then the store is created by calling *createStore* and passing over the Reducer as a parameter. \
\
Finally we need to call `store.subscribe(render)`. This makes sure that the *render* function is called whenever the state of the application changes.

## Implementing App Component <a href="#a50b" id="a50b"></a>

Now that we’ve implemented the main Redux building block in our application we need to implement the needed React components as well. We’re starting out by changing the default implementation of *App*component to the following:

```
import React, { Component } from 'react';
import { voteAngular, voteReact, voteVuejs } from './actions'
import './App.css';class App extends Component {
  constructor(props) {
    super(props);
    this.store = this.props.store;
  }  handleVoteAngular = () => {
    this.store.dispatch(voteAngular());
  }  handleVoteReact = () => {
    this.store.dispatch(voteReact());
  }  handleVoteVuejs = () => {
    this.store.dispatch(voteVuejs());
  }  render() {
    return (
      <div>
        <div className="jumbotron" style={{'textAlign': 'center'}}>
          <img src="ctsw_logo.png" height="96" alt="CodingTheSmartWay.com"></img>
          <h2>What is your favorite front-end development framework 2017?</h2>
          <h4>Click on the logos below to vote!</h4>
          <br />
          <div className="row">
            <div className="col-xs-offset-3 col-xs-2">
              <img src="angular_logo.png" height="96" alt="Angular" onClick={this.handleVoteAngular}></img>
            </div>
            <div className="col-xs-2">
              <img src="react_logo.png" height="96" alt="React" onClick={this.handleVoteReact}></img>
            </div>
            <div className="col-xs-2">
              <img src="vuejs_logo.png" height="96" alt="Vue.js" onClick={this.handleVoteVuejs}></img>
            </div>
          </div>
        </div>
      </div>
    );
  }
}export default App;
```

As you can see we’re making use of some Bootstrap CSS classes in the JSX code. A jumbotron is used as the main element which contains headlines and logos. For each logo we’re using the onClick attribute to connect an event handler method to the click event of the image.\
\
The three event handler methods *handleVoteAngular*, *handleVoteReact* and *handleVoteVuejs* are implemented as well. The only task which needs to be performed within the event handler methods is to dispatch the corresponding action to the store. To get access to the application store, the *store* object is passed to the component as a property:

```
function render() {
  ReactDOM.render(
    <div className="container">
      <App store={store}/>
    </div>,
    document.getElementById('root')
  );
}
```

## Implement Results Component <a href="#id-2c29" id="id-2c29"></a>

The display of the voting results is handled by another component: *Results*. Let’s create a new file *results.js* in folder *src/components*. The source code can be seen in the following listing:

```
import React, { Component } from 'react';class Results extends Component {
  constructor(props) {
    super(props);
    this.store = this.props.store;
  }  votesAngularInPercent() {
    if (this.store.getState().angular) {
      return (this.store.getState().angular / (this.store.getState().angular + this.store.getState().react + this.store.getState().vuejs)) * 100
    } else {
      return 0
    }
  }  votesReactInPercent() {
    if (this.store.getState().react) {
      return (this.store.getState().react / (this.store.getState().angular + this.store.getState().react + this.store.getState().vuejs)) * 100
    } else {
      return 0
    }
  }  votesVuejsInPercent() {
    if (this.store.getState().vuejs) {
      return (this.store.getState().vuejs / (this.store.getState().angular + this.store.getState().react + this.store.getState().vuejs)) * 100
    } else {
      return 0
    }
  }  votesAngularInPercentStyle() {
    return {
      width: this.votesAngularInPercent()+'%'
    }
  }  votesReactInPercentStyle() {
    return {
      width: this.votesReactInPercent()+'%'
    }
  }  votesVuejsInPercentStyle() {
    return {
      width: this.votesVuejsInPercent()+'%'
    }
  }  render() {
    return (
      <div>
        <span className="label label-danger">Angular: {this.votesAngularInPercent().toFixed(2) + '%'}</span>
        <div className="progress progress-striped active">
          <div className="progress-bar progress-bar-danger" style={this.votesAngularInPercentStyle()}></div>
        </div>
        <span className="label label-info">React: {this.votesReactInPercent().toFixed(2) + '%'}</span>
        <div className="progress progress-striped active">
          <div className="progress-bar progress-bar-info" style={this.votesReactInPercentStyle()}></div>
        </div>
        <span className="label label-success">Vue.js: {this.votesVuejsInPercent().toFixed(2) + '%'}</span>
        <div className="progress progress-striped active">
          <div className="progress-bar progress-bar-success" style={this.votesVuejsInPercentStyle()}></div>
        </div>
      </div>
    )
  }
}export default Results;
```

Again, the store is passed into the component as a property. The constructor is used to make the store available via *this.store*.\
\
In order to express the current voting results in percentage three helper methods are defined: *votesAngularInPercent*, *votesReactInPercent* and *votesVuejsInPercent*.\
\
Three additional helper methods (*votesAngularInPercentStyle*, *votesReactInPercentStyle* and *votesVuejsInPercentStyle*) are defined to return the CSS width value for the current voting result. This is used in the JSX code to set the style value of the progress bar element. \
\
The include the output of the Results component in our application make the following changes to *index.js*:

```
[...]
import Results from './components/results';
let store = createStore(myApp);function render() {
  ReactDOM.render(
    <div className="container">
      <App store={store}/>
      <hr />
      <Results store={store}/>
    </div>,
    document.getElementById('root')
  );
}store.subscribe(render);render();
```

First the import statements for *Results* is added and second the element `<Results store={store}/>` is added to the JSX code inside the render function. \
\
Having made these changes, you should see the final result of our voting application in your browser.
