Chaduvula Prasanth

Navigate back to the homepage

Redux Flow

Chaduvula Prasanth
January 22nd, 2020 · 3 min read

The live demo of the counter app builted in react using redux is here

Redux Flow

Getting Started with Redux

Redux is a predictable state container for JavaScript apps.

It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.

You can use Redux together with React, or with any other view library. It is tiny (2kB, including dependencies), but has a large ecosystem of addons available.

Why Redux

  • As the requirements for JavaScript single-page applications have become increasingly complicated, our code must manage more state than ever before. This state can include server responses and cached data, as well as locally created data that has not yet been persisted to the server. UI state is also increasing in complexity, as we need to manage active routes, selected tabs, spinners, pagination controls, and so on.

  • Managing this ever-changing state is hard. If a model can update another model, then a view can update a model, which updates another model, and this, in turn, might cause another view to update. At some point, you no longer understand what happens in your app as you have lost control over the when, why, and how of its state. When a system is opaque and non-deterministic, it’s hard to reproduce bugs or add new features.

  • In React Managing a local state in every component is not easy, when ever you want to access the state in children component, you have to access through porps which itself creates a problem of props drilling as data flow downwards in React

  • Redux allows you to manage the state of the application via a unidirectional flow where a child component can directly access the state from the redux store instead of getting state changes from parent components.

To use Redux application we have to install redux which is available as a package on NPM

1npm install redux

Flow

  1. When an user interacts with application, an action is dispatched
  2. The particular dispatched action goes to reducers and manipulates it
  3. A new state will be updated on the store
  4. Accordingly react component updates (rerenders)
  5. View changes on the user application

How the flow works in the application side

when ever user interacts with the application ( React component) then it goes to action -> reducers -> store -> React component.

ACTION CREATORS:

These are exactly that—functions that create actions. It’s easy to conflate the terms “action” and “action creator”, so do your best to use the proper term. in Redux, action creators simply return an action:

1function Doincrement(){
2 return {
3 type: "increment"
4 payload:"value"
5 }
6}

ACTION:

An object that contains information about how we want to change some data within our central state

1{
2 type: "increment"
3 payload:"value"
4}

DISPATCH:

A function that takes in an action, makes copies of the action, and sends them out to the reducers.

REDUCER:

A pure function that takes in an action and some existing data, changes the data according to the type and payload of the action, and then sends the updated data to the state.

Reducers specify how the application’s state changes in response to actions sent to the store. Remember that actions only describe what happened, but don’t describe how the application’s state changes. State An object that serves as the central repository of all data from the reducers.

STORE

The Store is the object that brings them together. The store has the following responsibilities:

It’s important to note that you’ll only have a single store in a Redux application. When you want to split your data handling logic, you’ll use reducer composition instead of many stores.

It’s easy to create a store if you have a reducer. we use combineReducers() to combine several reducers into one. We will now import it, and pass it to createStore().

Usage with react

React-Redux

With React-Redux, we use some components and functions to tie React and Redux together: Store, Provider, and Connect.

STORE:

The Store contains the consolidated reducers and the state.

PROVIDER:

The Provider is a component that has a reference to the Store and provides the data from the Store to the component it wraps.

CONNECT:

Connect is a function communicates with the Provider. Whatever component we wrap with Connect, that component will be able to get changes in the Store state from the Provider.

We can configure Connect to get just the part of the data we want from the Provider. Connect passes this down as props into the wrapped components.

The flow with react-redux looks like this

  1. Create the Provider
  2. Pass it a reference to our Redux Store
  3. Wrap any component that needs to interact with the Store with Connect
  4. Connect passes down the different pieces of state and any action creators we need as props down to the wrapped component.

Example : counter app in react with redux The live demo of the counter app is here

Folder structure in our React application

1-> src
2 >state
3 >actions
4 - index.js
5 >reducers
6 -index.js
7 >store.js
8 >components
9 -counter.jsx
10 >index.js
11 >types.js

Lets go to the index.js

1// index.js
2
3import React from 'react';
4import { render } from 'react-dom';
5import { Provider } from 'react-redux';
6import store from './state/store';
7import Counter from './components/Counter';
8
9render(
10<Provider store={store}>
11<Counter />
12</Provider>,
13document.getElementById('root')
14);

in types.js

1//types.js
2
3export const INCREMENT = 'increment';
4export const DECREMENT = 'decrement';
5export const RESET = 'reset';
6export const STEP = 'step';
7export const MAX = 'max';

in actions/index.js

1// actions/index.js
2
3import { INCREMENT, DECREMENT, RESET, STEP, MAX } from '../../types';
4
5export function DoIncrement() {
6 return { type: INCREMENT };
7}
8
9export function DoDecrement() {
10 return { type: DECREMENT };
11}
12
13export function DoReset() {
14 return { type: RESET };
15}
16
17export function DoStep(e) {
18 return { type: STEP, payload: e };
19}
20export function DOMax(e) {
21 return { type: MAX, payload: e };
22}

in reducers/index.js

1//reducers/index.js
2
3import { INCREMENT, DECREMENT, RESET, STEP, MAX } from '../../types';
4
5let intialState = {
6 count: 0,
7 step: 1,
8 max: 40
9};
10
11function counter(state = intialState, action) {
12
13 switch (action.type) {
14
15 case INCREMENT:
16
17 if (state.count < state.max) {
18 return { ...state, count: state.count + state.step };
19 } else {
20 alert(`you can't exceed more than ${state.max}`);
21 return state;
22 }
23 case DECREMENT:
24 if (state.count > 0) {
25 return { ...state, count: state.count - state.step };
26 } else {
27 alert("you can't go below 0");
28 return state;
29 }
30 case RESET:
31 return { ...state, count: 0 };
32 case STEP:
33 return { ...state, step: action.payload };
34 case MAX:
35 return { ...state, max: action.payload };
36 default:
37 return state;
38 }
39}
40export default counter;

in store.js

1//store.js
2
3import { createStore } from 'redux';
4import counter from './reducers/index.js';
5const store = createStore(counter);
6export default store;

in counter.jsx

1import React from 'react';
2import { connect } from 'react-redux';
3import { DoIncrement,DoDecrement,DoReset,DoStep,DOMax} from '../state/actions';
4
5class Counter extends React.Component {
6 render() {
7 let { count, step, max, dispatch } = this.props;
8 return (
9 <div className="wrapper rwrapper">
10 <h1 className="counter">{`count by ${step} and max up to ${max}`}</h1>
11 <div className="counterValue-div">
12 <h2 className="counterValue">{count}</h2>
13 </div>
14 <div className="btn-wrapper1">
15 <button className="inc btn" onClick={() => dispatch(DoIncrement())}>
16 Increment
17 </button>
18 <button className="dec btn" onClick={() => dispatch(DoDecrement())}>
19 Decrement{' '}
20 </button>
21 <button className="reset btn" onClick={() => dispatch(DoReset())}>
22 Reset
23 </button>
24 </div>
25 <p className="text">STEP</p>
26 <div className="btn-wrapper2 rbtn">
27 {[5, 8, 10, 12, 14, 16].map(e => (
28 <button
29 onClick={() => dispatch(DoStep(e))}
30 className={`btn1 ${step == e ? ' active' : ''} `}>
31 {e}
32 </button>
33 ))}
34 </div>
35 <p className="text">MAX</p>
36 <div className="btn-wrapper2 rbtn-wrapper2">
37 {[50, 100, 150, 200, 250, 300].map(e => (
38 <button
39 onClick={() => dispatch(DOMax(e))}
40 className={`btn1 ${max == e ? ' active' : ''} `} >
41 {e}
42 </button>
43 ))}
44 </div>
45 </div>
46 );
47 }
48}
49
50function mapStateToProps(state) {
51 return { count: state.count, step: state.step, max: state.max };
52
53}
54export default connect(mapStateToProps)(Counter);

The live demo of the counter app is here

More articles from Chaduvula Prasanth

Authentication vs Authentication

Learn what is Authentication, Authentication and difference between them

January 21st, 2020 · 1 min read

How To Do Basic Routing In React Using React Router Dom

Learn the basics of routing, how to make router, path and how to link pages on the basis of the URL path.

December 19th, 2019 · 1 min read
© 2020 Chaduvula Prasanth
Link to $twitterLink to $githubLink to $linkedin