This article mainly focuses on implementing some good practices I follow when building large scale applications with React and Redux.
Differentiate Presentational Components and Container Components.
When we are architecting a react application with redux, we should split our components into presentational and container components.
Presentational components are components that render HTML. All our presentational components are stateless components, so are written as functional stateless components unless they need state and lifecycle hooks. Presentational components will not interact with redux store for state. They receive data via props and render it.
Container components are for getting data from redux store and providing the data to the presentational components. They tend to be stateful.
Presentational Component should be stateless functional component as shown:
Container Component should be stateful functional component until unless you are forced to use React component life cycle methods.
Points to be noted:
- We can see improved performance when using stateless functional components.These components avoid unnecessary checks and memory allocations and are therefore more performant.
- It will be easy to test a component , if you write the component as simple as possible by splitting presentational components and container components.
Use bindActionCreators for dispatching actions
Redux’s event dispatching system is the heart of its state management functionality. However, it can be tedious to pass down the dispatch function as a prop to every component that needs to dispatch an action.
Instead do this.
In the above code filterTalentPoolDataBySkills in bindActionCreators is available as this.props.filterTalentPoolDataBySkills to dispatch your action. It will make it easier to maintain the code for long run.
Try to avoid using setState and component lifecycle hooks when using Redux:
Manage the application state using redux store when it is global state. Try to avoid using setState in your component when you are using state management libraries like redux. Use component state when it makes sense ie. A Button component that shows a tooltip when hovered would not use Redux.
Avoid Doing this.
Instead do this.
Here we used the redux store to get state and render it in the view directly. There is no need of using setState and component lifecycle hooks again. Redux is there to do the state management job for you.
Using .bind() in best way:
There are two ways of binding the custom component’s this scope.
- Binding them in constructor.
With this way only one extra function is created at the time of component creation, and that function is used even when render is executed again.
2. Binding at the time of passing as prop value.
.bind() method creates a new function each time it is run, this method would lead to a new function being created every time when the render function executes. This has some performance implications. In small applications we cannot notice them, where as in large applications we can notice them. So its not prefferable to bind a function at the time of passing as a prop value.
- Its better to bind your custom functions in constructor.
- There is a Babel plugin called Class properties transform . You can write auto-bound function using the fat-arrow syntax.
If we see the above code there are no functions to bind.
Use Accessor Functions
For better code refactoring move all your functions which do filtering , parsing and other data transformation logics into seperate file and import them to use those functions inside your connect method of react-redux as shown.
By doing this it will be easy to add flow types for your functions.
Write cleaner code using ES6 Features
Writing cleaner code will make the developers life easy to understand and maintain the code. ES6 features will give us much cleaner way of writing code in React.
Use Destructuring & spread attributes:
Instead do this.
Use Arrow functions:
Instead do this.
Use Flow Types
One thing is certain that type checking is expected to be the future of JS. Generally many developers have a confusion between what to implement between flow and typescript and how smoothly they can be integrated into a current project.
Typescript is more sophisticated to integrate into current project and flow feels simple to introduce, admitting with a warning that it might be inspecting less of your coding as expected.
Benifits in using flow:
- On time detection of bugs or errors.
- Communicates the purpose of the function.
- It Scales Down Complex Error Handling.
- Wipes Out Runtime Type Errors.
Use axios library for http requests over jQuery ajax:
Fetch API and axios are the most preferable ways of making http requests. Between those two there are some advantages of using axios library. They are
- It allows performing transforms on data before request is made or after response is received.
- It allows you to alter the request or response entirely (headers as well). also perform async operations before request is made or before Promise settles.
- Built-in XSRF protection.
Use styled-components to style your components
The basic idea of styled-components is to enforce best practices by removing the mapping between styles and components. This way, you can colocate your components with their corresponding styles — resulting in localised class names that do not pollute the global css namespace.
If you decide to use styled-components, do not forget to install plugin to support syntax highlighting in strings or maybe help creating a new one.
Test your React components
The goal of unit testing is to segregate each part of the program and test that the individual parts are working correctly. It isolates the smallest piece of testable software from the remainder of the code and determines whether it behaves exactly as you expect. We can find bugs in early stage.
Use ES Lint for better coding conventions.
Well run projects have clear consistent coding conventions, with automated enforcement. Besides checking style, linters are also excellent tools for finding certain classes of bugs, such as those related to variable scope. Assignment to undeclared variables and use of undefined variables are examples of errors that are detectable at lint time.
For React specific linting rules go with esint-plugin-react .