Redux State Management Introduction and Latest Top 50+ MCQs

Redux State Management Introduction

Redux is a predictable state container for JavaScript and comes as an external library which can be used together with front-end frameworks like React, Angular, Ember.js, Backbone etc. However Redux is most often used together with React.

The Problem With Traditional MVC Architecture

Before diving deeper into the concepts of Redux let’s first focus on the problems it solves. The Model-View-Controller (MVC) pattern is familar to most front-end web developers nowadays. This pattern describes a separation between the data (model), the presentation (view) and the application logic (controller). This ensures that your application is built in a structured way and that you achieve a separation of concerns.

However the disadvantage is that you’re loosing control of your data flow. In general the data flow is bi-directional. The user input in one component can affect other components and vice versa. Controlling the flow of data and making sure that all user interface components update accordingly is an error-prone task.

How State Management Solves The Problem

By using Redux we’re solving this problems by introducing a central data store in our application. The store contains the state of the application and is the source of truth for components. By using the store concept you do not need to synchronize state between components manually. Instead you can fully rely on the Redux store at any time.

Building Blocks Of Redux

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

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

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

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:

1*fcbWaGi9QCNYa5DoUYmERw

Building A Sample React-Redux Application

What We’Re Going To Build

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:

1*bUP 9ECqRL psBnC7DmuhA

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

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

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

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 angularreact 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

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

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 handleVoteAngularhandleVoteReact 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

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: votesAngularInPercentvotesReactInPercent and votesVuejsInPercent.

Three additional helper methods (votesAngularInPercentStylevotesReactInPercentStyle 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.

Redux State Management MCQs

1. Which of the following is not an implementation of Flux?

Answer:- Fluxit

2. Modularity in Redux is achieved through ________________

Answer:- Reducers

3. In Redux, state variables and objects are never mutated. Instead, new ones are produced.

Answer:- True

4. The function random() produces a new random number between 0 and 1 every time you run it. Is this a pure function?

Answer:- False

5. Data flow in Redux is:

Answer:- Uni-Directional

6. Which of the following is not true about Pure Functions

Answer:- Can make API calls

7. In Redux Action Types have to be defined as Strings

Answer:- True

8. Which of the following Action Objects are syntactically correct?

Answer:- { type: ‘ADD_TODO’, text }

9. Actions in Redux

Answer:- Send data to Store

10. Which of the following functions can be used to dispatch actions in Redux?

Answer:- All the options mentioned

Action Creators in Redux

Answer:- All the options mentioned

12. What is the input for the dispatch function?

Answer:- Action Object

13. Following function is a __________?

Answer:- (previousState, action) => newState

Reducer

14. createStore is a function to be imported from ____________

Answer:- Redux

15. Which of the following statements about Reducers is not true?

Answer:- Can make API calls

16. combineReducers aggregates the output of reducers into a single object representing application state.

Answer:- True

17. Which of the following can be done in a Reducer?

Answer:- Perform Calculations

18. Presentational components of React are connected to the container components of React.

Answer:- True

19. State Changes in Redux are stored in such a way that _____________

Answer:- State changes are stored as new state with references to old state for unchanged sections of the state tree.

20. Which of the following can be done inside a reducer?

Answer:- Call a pure function

21. What is the helper function that Redux provides for making root reducer?

Answer:- CombineReducer()

22. Redux bindings to React are to be imported from ____________.

Answer:- ReactRedux

23. How to access Redux state from store?

Answer:- getState()

24. One can deregister listeners on store by calling function returned by _______________.

Answer:- subscribe(listner)

Click here to read more Interview Questions and Answers

27. Which of the following is not api of redux library

Answer:- connect()

28. React bindings for Redux are enabled by default.

Answer:- False

29. Which of the following is a signature of a reducer function?

Answer:- function name(state, action)

30. How can initial state be passed to store the, using the createStore function?

Answer:- Pass it as second aurgument

31. The function double is defined as below. Is this a pure function?

Answer:- const double = x => x * 2;

True

32. How is the context of store passed to React components?

Answer:- Using Provider

33. Redux applications follow _____________________

Answer:- Functional Programming

34. What are middleware used for?

Answer:- To create new dispatch function

35. How to register for listeners on store?

Answer:- subscribe(listener)

36. Redux can be used with React, AngularJS, BackboneJS and many others.

Answer:- True

37. Which components take care of connecting to Redux store for data fetching and state updates?

Answer:- Container

38. How do you bind action creators with dispatch function?

Answer:- bindActionCreators

Click here to read more Blogs

About Author


After years of Technical Work, I feel like an expert when it comes to Develop wordpress website. Check out How to Create a Wordpress Website in 5 Mins, and Earn Money Online Follow me on Facebook for all the latest updates.

Leave a Comment