Redux provides an easy way to centralize the state of your application. There are three basic properties to know in Redux. Action, Store, Reducer. We will cover all these properties one by one.
The Redux Cycle
The redux cycle is composed of Action, Store and Reducers. Action is like a message that we send or dispatch to our central Redux Store. The Store is the central part and it saves the global app state. Reducers calculates the next state ie. they handles the main flow. If any change in state occurs, the reducer will check which action type is triggered and then reducer changes the state for that particular action type.
I have learned about the basic redux flow. I created a voting app which with the help of redux will do comparison between three technologies.
The Basic Directory Structure
In the above image, there is a src folder which contains the main flow of the application. It has sub-directories such as components, reducers and actions.
In actions folder → index.js
// Define action types as constants
export const VOTE_REACT = 'VOTE_REACT';
export const VOTE_ANGULAR = 'VOTE_ANGULAR';
export const VOTE_VUEJS = 'VOTE_VUEJS';
// Action creators
export const voteReact = () => {
return {
type: VOTE_REACT
};
}
export const voteAngular = () => {
return {
type: VOTE_ANGULAR
};
}
export const voteVueJs = () => {
return {
type: VOTE_VUEJS
};
}
Code language: JavaScript (javascript)
The above index.js file contains the action type for three technologies – Angular, React and VueJs.
In reducers→ index.js
const initialState = {
angular: 0,
react: 0,
vuejs: 0
}
export default (state = initialState, action) => {
switch (action.type) {
case 'VOTE_ANGULAR':
console.log('Vote Angular!');
return Object.assign({}, state, {
angular: state.angular + 1
});
case 'VOTE_REACT':
console.log('Vote React!');
return Object.assign({}, state, {
react: state.react + 1
});
case 'VOTE_VUEJS':
console.log('Vote VueJs');
return Object.assign({}, state, {
vuejs: state.vuejs + 1
});
default:
return state;
}
}
Code language: JavaScript (javascript)
In the above index.js file, the reducer takes 2 arguments (state, action). So depending upon the type of the action the reducer changes the state and returns it to the global store.
In src→ index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import './index.css';
import App from './App';
import myApp from './reducers';
import Results from './components/results';
import registerServiceWorker from './registerServiceWorker';
// Create the Redux store for the application
let store = createStore(myApp);
function render() {
ReactDOM.render(
<App />,
document.getElementById('root')
);
registerServiceWorker();
}
store.subscribe(render);
render();
Code language: JavaScript (javascript)
This index.js is the file where you initialize the app and call ReactDom.
src→ App.js
import React, { Component } from 'react';
import { voteAngular, voteReact, voteVueJs } from './actions/index';
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 (
// Your JSX code goes here
);
}
}
export default App;
Code language: JavaScript (javascript)
What is your favorite front-end framework in 2017
The above App.js is the main component of the react application.
Components→ results.js
import React, { Component } from 'react';
export default 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-danger"> React: {this.votesReactInPercent().toFixed(2) + '%'}</span>
<div className="progress progress-striped active">
<div className="progress-bar progress-bar-danger" style={this.votesReactInPercentStyle()}></div>
</div>
<span className="label label-danger"> VueJs: {this.votesVueJsInPercent().toFixed(2) + '%'}</span>
<div className="progress progress-striped active">
<div className="progress-bar progress-bar-danger" style={this.votesVuejsInPercentStyle()}></div>
</div>
</div>
);
}
}
Code language: JavaScript (javascript)
The above results.js file contains the component called Result.
All the components of the application will come under the components folder.
The output of the above application