• Blog Home
  • Tech Talk
    • Best Practices
    • Java
    • .NET
    • Mobile
    • UI/ UX
    • Systems Engineering
    • Quality Assurance
  • ClubM

Sign in

  • Mazarin Corporate Site »
Mazarin Blog
stay connected
Join us on Facebbook! Follow Us on Twitter! Subscribe to our RSS Feed!
Sep
15
2017
Tech Talk

Productive Development With React Redux

Author Article by Admin editor    Comments No Comments

Introduction to Redux and React

React is a JavaScript library  and not a framework which mainly focuses on User Interface .It has a one way reactive data flow that forces you to think in terms of components. This model of thinking fits user interfaces well and the concept of state and where it belongs must be carefully thought of.

State management is the critical and difficult situation although it has many solutions. Redux gives the great support to handle the State Management in user interface.

Redux was created by Dan Abramov around June 2015. It was inspired by Facebook’s Flux and functional programming language Elm.

Redux is a framework that controls states in a JavaScript app. According to the official site:“Redux is a predictable state container for JavaScript apps.”

Redux is usually used for application state management. Redux maintains the state of a whole application in a single immutable state tree (object), which can not be changed directly. When something changes, a new object is created.

Without Redux and with Redux application state behavior

Figure 1 : Without Redux and with Redux application state behavior (Source: https://www.slideshare.net/binhqdgmail/006-react-redux-framework)

 

Suppose ‘A’ component has an attribute of user name. When the state of the username is changed, it should be reflected to the other components(‘B’). In this situation, the data has to be retrieved  through an API call from the back end or a separate method has to be called to change the state of username in ‘B’ component.

A separate store can be maintained  to keep the state of the user name and  the state can be retrieved  from  the store to ‘B’ component when using Redux.

 

Advantages of Using Redux?

 

1. Predictability of outcome
Syncing the current state with actions and other parts of the application is simple and straightforward since the correct information is always available in store.

2. Maintainability
Because of the predictable outcomes and strict structure, maintainability is easy.

3. Organization
Redux is highly concentrated about how code should be organized ,which make more consistent and  flexible for  a team to work with.

4. Server rendering
This is very useful, especially for the initial render, making for a better user experience or search engine optimization.It can be achieved by passing the store created on the server to the client side

5. Developer tools
Developers can track everything going on in the app in real time, from actions to state changes.Chrome has  redux devtools. Developers can easily debug and catch on changes or errors.

6. Ease of testing
Unit testing can be done via redux.Generally,test cases are written for small functions that are independent and only capable of doing one thing and the code is mostly functions small, pure and isolated.

 

Data Flow Across Components With and Without Redux

 

Redux is a container for managing both data-state and UI-state in JavaScript applications. It is also a framework-agnostic, so while it was written with React in mind, it can even be used with Angular or a jQuery application.

As the requirement for JavaScript application have become increasingly complicated, the code must manage more state in order to facilitate the high interactive complex UIs. Since React flows data through components in an unidirectional way from parent to child, it becomes a huge challenge to manage state throughout the multiple components. As an example,show below is how  two non-parent child components would communicate in React.

Without Redux

Figure 2 : Without Redux – Poor practice when component-to-component communicate that doesn’t have parent to child relationship

React does not recommend direct component-to-component communication this way (that does not have parent to child relationship).  React has features to support this approach,however, it is considered poor practice by many because it is error prone and leads to spaghetti code – an old term for code that is hard to follow.

React doc states it as follows:

“For communication between two components that don’t have a parent-child relationship, you can set up your own global event system. … Flux pattern is one of the possible ways to arrange this.”

This is where Redux comes in handy. Redux offers a solution of storing all application state in one place, called a “store”. Components then “dispatch” state changes to the store, not directly to other components. The components that need to be aware of state changes can “subscribe” to the store.

With Redux components are dispatching and subscribing state from the store

 

 Figure 3 : With Redux components are dispatching and subscribing state from the store

The store is acting as the “middleman” for managing state of the application. With the involvement of Redux, components do not need to communicate with each other, but rather all state changes must go through the single source of truth, the store.

 

Main Guiding Principles of Redux

 

Redux can be described in three fundamental principles:

1. Single source of truth
The state of the whole application is stored in an object tree within a single store. Since all state resides in one place, Redux calls this the single source of truth.
The data structure of the store is ultimately up to the developer and it will help to develop universal applications. Single state of tree also makes it easier to debug or inspect an application.
Some functionality which has been traditionally difficult to implement – Undo/Redo, for example can suddenly become trivial to implement, if all of your state is stored in a single tree.

2. State is read-only
In Redux only way to change the state is to emit and action, an object describing what happened.
This ensures the application cannot modify the state directly. Instead, Redux dispatches an “actions” to express an intent to change the state in the store. As actions are just plain objects which can be logged, stored and later replayed for debugging or testing purposes.
The store object provides API with the following four methods:

  • store.dispatch(action)
  • store.subscribe(listener)
  • store.getState()
  • replaceReducer(nextReducer)

So as mentioned there’s is no method for setting state and dispatching an action is the only way to change the state in store.

var action = {
type: 'ADD_USER',
user: {name: 'Bravo'}
}
// Assuming a store object has been created already
store.dispatch(action);

The dispatch() method sends an object to Redux, as an action which hold the type and all other data that need to update the state in store. The design and the content of the action object is totally up to the developer and the situation.

3. Changes are made with pure functions

As discussed Redux does not allow the application to make any direct state changes. Instead it needs to dispatch actions by describing what needs to be changed.

Therefore,  Redux uses pure functions (pure reduces) to update the state tree. The term of “pure function” can be described as follows:

  • The function always evaluates the same result value given that the argument remains the same.
  • The function cannot depend on any state or value that may change during the execution of the function.
  • It does not make any outside API or database calls.

Reducers are just pure functions that take the previous state and an action, and return the next state. Important thing is here reducers always need to return new state objects, instead of mutating the previous state.The figure below describes the architectural data flow design when using redux with react.

Architectural design of connection react with redux

 Figure 4 : Architectural design of connection react with redux

 

Introducing Actions and Reducers Redux

Actions are plain JavaScript objects.It must  have a ‘type’ property that illustrates the type of action being performed. It means that identifies to the consumer the nature of the action that has occurred. ‘type’ is usually a string constant or a Symbol. If two types are the same, they MUST be strictly equivalent (using ===).

const SHOW_GREEN= 'SHOW_GREEN'
{
  type: SHOW_GREEN,
  text: 'It says GO'
}

You can design the object which can uses more attributes rather than type . Those are error, payload and meta property.
The ‘payload ’ property may be any type of value. It represents the payload of the action. Any information about the action that is not the type or status of the action should be part of the payload field.For example, if some values are to be passed as parameters to API call , they can be added into the ‘payload ’section.
The ‘meta’ property may be any type of value. It represents any extra information that is not part of the payload.
The ‘error’ property may be set to true if the action represents an error.
An action whose error is true is analogous to a rejected Promise. By convention, the payload should be an error object.
If error has any other value besides true, including undefined and null, the action must not be interpreted as an error.
By convention, if error is true, the payload should be an error object. This is akin to rejecting a promise with an error object.

 

Action Creators

Action creators is a plain function that returns an action object.

function showGreen() {
  		return {
    		type: SHOW_GREEN
  		};
	}

 

Are Action Creators Mandatory?

 

It is upto your application design. Suppose the application has an action which has been used in several places, it is beneficial  to implement action creators, whereas if there is an action which has been used only once throughout the application, then it is a better choice to implement actions rather than action creators.

Action Creators are used  to keep consistency and maintainability,because everything is abstracted into a function.
For simple apps or those with simple actions, this is a perfectly reasonable option. Sometimes are just not worth the effort,so it will be least boilerplate.

 

Reducers

Reducers are pure functions that takes the previous state then an action and returns the next state.It means reducers are consider about “what store was before “ then they listen for actions and dispatch something to listening components respectively. Finally will combine all reducers,then keeps tabs of anything happening to the entire state of the application.

The important thing to keep in mind is that reducers do not mutate the state. In fact, it clones a copy of the state and applies the new changes instead.

It is important to keep in mind that it’s  arguments are never mutate inside a reducer and also never performs side effects like API calls and routing transitions inside the reducer.It is not advisable to call non-pure functions such as Date.now() or Math.random() inside of the reducer.

 

Store

The store is not a class ,It is  just an object holding a few methods. A store holds the whole state tree of an application and the only way to change the state inside it is to dispatch an action on it.There should only be one store for the  whole application. When the application is growing ,it is good to keep a single store  with a single root reducing function, instead of adding stores. Root reducers are split into smaller reducers, independently operating on the different parts of the state tree.

According to  figure 4 API method get/post, set/retrieve data with connection action creators and then connect with reducer and store, get the new state changes and connect with the user interface

 

Best Practices

In Redux-React development care must be taken when enforcing good patterns, as you might find yourself regretting the decision to use Redux. Following are some best practices that should be considered:

Redux Practices

  • Do not mutate state, copy it, using immutable data structures

The code used will be easily understood if the component state is immutable. This way, the state changes are more explicit and easy to test. Based on state, React renders the user interface and if state is mutated React re-renders the component. If the state is mutated directly, it will be very difficult to debug and test the state change. Therefore, do not mutate it, instead, create a changed copy of it.

A reducer is the only place that changes the application’s state. It receives the old state and an action as inputs and returns the next state. A reducer should never mutate its input. If this is attempted, Redux will provide a warning that this is not a reducer’s intended function. It is very rare that the old state in reducers is mutated and using an immutable object to represent the state is not necessary. This concept should be followed by a team. If .push() method is used, the state is then mutated, instead, use .concat() to make a copy of array. But what if the state is mutated outside of a reducer? There is a possibility of mutating the state by mistake. Redux Devtools can be used to find where the state of the application has gone wrong, however, this does not help in identifying why and or where it was mutated.

Immutable.js library helps to reduce this issue because with this the state tree cannot be mutated in any point of the code. Every operation performed on the state object will retrieve a copied instance, instead of changing the current one. Also in JavaScript, List, Maps etc. are mutable. As it is difficult to handle immutability in JavaScript, using libraries such as immutable.js makes development easier. Also using immutable data leads to garbage thrashing if data structures are constantly cloned when performing mutation, but with ImmutableJS it returns new reference without cloning the underlying data.

  • Centralize state: Single source of truth

App state can be easily maintained if all state is stored in one place. This is called a single source of truth. Debugging and development becomes easier and faster in this way. If the single source of truth rule is not adhered to, the following benefits will be lost:

  • Deterministic view render
  • Deterministic state reproduction
  • Time travel debugging
  • Easy testability
  • Avoid Nested state

It is considered to be better to have the state value as flat instead of a tree structure. If the state is nested it will be difficult to check whether the state is changed or not. To update state, if the state is nested, React needs to make a lot of value equality checks. By making state simple the performance of react can be optimized.

  • Move logic to Actions Creator instead of Reducer, Reducers must be pure

Reducer should only update the state; there should be no logic in reducers. Reducers should be simple and pure. Pure functions will have following characteristics:

  • No outside network or database calls.
  • Return value only depends on its parameters.
  • Arguments should not be changed, immutable.
  • When pure functions are called with same set of arguments, it always returns same values.

Business logic belongs to action creators. Redux sagas or redux thunk can be used in Action creators.

  • Action Strategies

Using String literals is a good way to distinguish between action types, however, whether they are unique globally must be ascertained. To ensure uniqueness it is recommended to make action types as constants. This can be achieved through the use of action creators, a function which creates and returns action objects.

 

React Best Practices

 

  • React’s Synthetic Events

React event object is wrapped in a Synthetic Event object. The objects received at an event handler will be reused for other events to increase performance. So accessing the event object’s properties asynchronously will be impossible since the event’s properties have been reset due to reuse.

This issue can be avoided by storing the event’s property inside its own binding.

  • Stateless Component

It is recommended to have more stateless components in app. It will increase reusability of the component. It is also easy to test and debug a stateless component.

  • Imports

It is good to import a specific function from the file instead of full libraries. This way  the size of the application can be reduced.

Instead of

  • Bind the functions in the constructor method

Calling bind or arrow functions in render as shown below has performance implications since it creates a brand new function on every single render. It is recommended to bind the functions in constructor method. This anti pattern can be caught using eslint-plugin-react.

  • Avoid using variable directly in component

Avoid using variable directly. React treats [ ] this as a new variable and will re – render component on any change. This will destroy every pure render optimization. Instead it can be defined outside and used. Also use getDefaultProps instead of defining a variable.

  • Adding Getters

 If the prefix get is added before functions, It will eliminate the extra function execution with every call to get.

 

Usage of the Redux with React

 

following section describes the simple user creation process with React and Redux application. Here it shows the important code sections and how your code separates to the different sections such as component, action, logic and reducer using simple user created example. Basically, the UI component contains the presentational forms of the application and it will invoke the relevant actions through the logic middleware mapping. According to the Redux documentation, actions are payloads of information that send data from your application to store. So, in action function, it will dispatch an action with a defined action type. According to the dispatched action type, relevant logic functions will be executed. Logic or the logic-middleware listens to the action type and will perform the necessary business logic. Then the reducer will update the store with updated data-state and UI-state accordingly.

Create user component(UserForm.jsx)

User related actions(UserAction.js)

User related logic(UserLogic.js)

User related reducers(UserReducer.js)

 

Tools & Technologies

 

Developing React-Redux applications is a little more complex.  There are powerful tools available to make the process productive.

 

Chrome’s React/Redux Developer Tools

Debugging Javascript is very complex, especially if it is a React app. React Developer Tools is a tool that allows you to inspect a React Renderer, including the Component hierarchy, props, state, and much more. It is a very important tool in your development.

  • Arrow keys for navigation
  • Right click a component to show in elements pane, scroll into view, show source,
  • Use the search bar to find components by name
  • A red collapser means the component has state/context

 

The Ducks’s File Structure for Redux

Ducks helps to package all the related code into a Redux module. Each module contains all of its related constants, actions/action creators, and its reducer. If other modules need this module, it can be imported or exported. There are some rules that needs to be followed when writing Ducks module:

  1. Must export a default function called reducer()
  2. Must export its action creators as functions
  3. Must have action types in the form npm-module-or-app/reducer/ACTION_TYPE
  4. May export its action types as UPPER_SNAKE_CASE, if an external reducer needs to listen to them, or if it is a published reusable library

 

Webpack

Webpack is a powerful tool which provides options for minification and sourcemap for your bundle. Also it can be run as middleware through a custom server called webpack-dev-server, which supports both live reloading and hot reloading. But major drawback with webpack is that it is difficult to configure. By injecting a global variable named process.env.NODE_ENV. with webpack, it can be made certain that the output bundle is performance optimized and error messages are stripped away.

new webpack.DefinePlugin({ ‘process.env.NODE_ENV’, JSON.stringify(‘production’) })

 

Eslint

Eslint can be used to show errors and warnings directly in the editor and it will also fix those errors automatically.

 

React Hot Loader

React hot loader helps for live reloading of the code. When the code is edited and saved, the browser will automatically get the new changes without reloading it manually. Most important thing is React components are reloaded without losing the Redux state.

 

Editors, IDEs

Atom, Nuclide, Webstorm, Visual studio code are some available editors/IDE for React-Redux application development. Visual studio code is free and open source and it supports debugging, embedded Git control and more features. It is developed by microsoft for Windows as well as for Linux. Atom is a text editor which is used by developers for most of the technologies. It has an active community, so plugins and enhancements will always be available. Sublime Text is also another editor with a huge active community and used by more developers. Webstorm is built on top of open source intellij platform, it supports code completion, on the fly code analysis, code formatting, refactoring..etc.

 

Unit Testing

One of the last challenges faced in React Redux development is unit testing. Unit testing will help to ensure that the code behaves as expected.When working in a team, code base gets bigger, it is impractical to manually check if every function or class behaves as expected. Writing automated tests to  check whether the code is working properly whenever the code is changed, will save time, which can be spent on debugging.Jest is one of the recommended test engines for React Redux applications. Mocha and Jasmine are some other available testing frameworks.Listed below are some of the advantages of using Jest:

  • Minimum time to setup the project
  • Ability to run tests in parallel where Mocha does not have this ability
  • Snapshot testing which helps to reduce number of tests to write
  • In-built Manual mocking
  • Code coverage comes right out of the box

When writing unit test for React-Redux application, unit testing can be broken down in the following manner:

  • Presentational components: to test rendering and event callbacks
  • Container components: to test rendering and Redux connections
  • Actions: to test whether expected data is returned
  • Reducers: to test logic and check whether reducers are pure or not.
  • End to End test:  to test rendering the root component and simulation of user interactions.

 

Conclusion

The number of developers using React and Redux nowadays for their web application development is increasing. By following best practices and using available tools and technologies developers can make their development much faster and more productive with an updated quality of code.

 

References

  1. http://redux.js.org/
  2. https://medium.com/front-end-developers/react-redux-tutorial-d1f6c6652759
  3. https://css-tricks.com/learning-react-redux/
  4. http://nalwaya.com/javascript/2016/05/02/react-js-best-practices.html
  5. https://getstream.io/blog/react-redux-best-practices-gotchas/
  6. https://medium.com/@scbarrus/the-ducks-file-structure-for-redux-d63c41b7035c
  7. https://medium.com/javascript-scene/10-tips-for-better-redux-architecture-69250425af44
  8. https://www.codementor.io/mz026/getting-started-with-react-redux-an-intro-8r6kurcxf
  9. https://teropa.info/blog/2015/09/10/full-stack-redux-tutorial.html

 

Authors

 

  • Lahiru Yapa
  • Vithiya Sivapalan
  • Thanuja Pubudini

Related Post

MS SQL Server BI (Business Intelligence)
Test Automation of Mobile Applications using Appium
Moving towards Microservices – Challenges and Common Pitfalls
Let’s move to NoSQL Databases with MongoDB – Mazarin
Company Culture
Serverless Architecture with AWS Lambda
All You Need To Know About DevOps
Let it Snow ’13

On this Page

  • Introduction to Redux and React
  • Advantages of Using Redux?
  • Data Flow Across Components With and Without Redux
  • Main Guiding Principles of Redux
  • Introducing Actions and Reducers Redux
  • Reducers
  • Store
  • Best Practices
  • React Best Practices
  • Usage of the Redux with React
  • Tools & Technologies
  • Chrome’s React/Redux Developer Tools
  • The Ducks’s File Structure for Redux
    • Conclusion
    • References
    • Authors
  • Related Post
Tags: Components, Functions, Javascript, Mazarin, React, Redux
Did you enjoy reading this article? Share it! Share on Facebook Tweet this! Bookmark on Delicious StumbleUpon Digg This!

Related Posts

  • Serverless Architecture with AWS Lambda
  • Let’s move to NoSQL Databases with MongoDB – Mazarin
  • Elements of CultureCompany Culture
  • What is Docker ? Getting Started with Docker
avatar

About the Author:

Leave a comment

Click here to cancel reply.

CAPTCHA
Refresh

*

Follow Us on Twitter!

On this Page

  • Introduction to Redux and React
  • Advantages of Using Redux?
  • Data Flow Across Components With and Without Redux
  • Main Guiding Principles of Redux
  • Introducing Actions and Reducers Redux
  • Reducers
  • Store
  • Best Practices
  • React Best Practices
  • Usage of the Redux with React
  • Tools & Technologies
  • Chrome’s React/Redux Developer Tools
  • The Ducks’s File Structure for Redux
    • Conclusion
    • References
    • Authors

Related Post

Sass and LESS: An Introduction to CSS Preprocessor...
Azure Functions – Learn more about it
Firebase – Mobile Application Development &#...
Serverless Architecture with AWS Lambda
Let’s move to NoSQL Databases with MongoDB &...
Beginners’ Guide to CSS (CSS for dummies)
Company Culture
What is Docker ? Getting Started with Docker
Hybrid Mobile App Development with Ionic and Angul...
Test Automation of Mobile Applications using Appiu...
What Power BI Can Do – Major Benefits
Data Mining using SQL Server Analysis Server
Learn Cucumber Test Automation with Ruby Core Fram...
How to Succeed With Designing Scalable Web Apps
Importance of Big Data and Managing Data with Elas...
An Introduction to Node.js – Kickstarter
MS SQL Server BI (Business Intelligence)
How To Start Cloud Computing with AWS
What is NFC – The Ultimate Guide
5 Principles: How To Use Lean Startup Towards A Su...
Avatars by Sterling Adventures

Team Mazarin

A team of individuals dedicated to share common goals and vision of the company. Mazarin's endowed team consists of Managers, Software Engineers, User Interface Engineers, Business Analysts, Finance and Administration. We are a blend of quality people. We strive to maintain the open culture and work in close association. The way we work enables everyone to contribute while feeling contented sharing opinions and ideas to deliver the best software solutions.

Read More

Mazarin © 2023. All Rights Reserved.