React Best Practices and Security

Last Updated on Oct 11, 2023

Universally accepted and well known in the field of front-end technologies, ReactJS is a popular name. It is a flexible open-source JavaScript library that is used to create unique and innovative user interfaces. Through this blog, we aim to bring all the insights and React best practices to help Reactjs developers and businesses build great and high-performing applications. Let’s start with the project structure.

1. React Folder Structure Best Practices

While creating a react project, the first step is to define a project structure that is scalable. You can create a new base react application structure by using the npm command ‘create-react-app’. The below screenshot displays the basic react app folder structure.

React folder structure may differ based on project specification and complexity. There are various reactjs best practices that can be taken into account while defining project architecture:

1. Folder Layout

The architecture focuses on reusable components of the react developer architecture so that the design pattern can be shared among multiple internal projects. Hence the idea of component-centric file structure should be used which implies that all the files related to a different component (like test, CSS, JavaScript, assets, etc.) should be kept under a single folder.

This is another approach used in grouping the file types. In this, the same type of files is kept under one folder. For example

The above structure is the basic example. The folders can be further nested based on requirements.

2. CSS in JS

In a large project, styling and theming can be a challenging task like maintaining those big scss files. So, the concept of CSS-in-JS solutions ( i.e. put CSS in JavaScript ) came into the picture. Following libraries are based on this concept.

  • EmotionJS
  • Styled Components
  • Glamorous

Among these libraries, you can use based on the requirement like for complicated themes, you can choose styled-components or Glamorous.

3. Children Props

Sometimes it is required to render method the content of one component inside another component. So we can pass functions as children props which get called components render function.

4. Higher-Order Components (HOC)

It’s an advanced technique in React which allows reusing component logic inside the render method. An advanced level of the component can be used to transform a component into a higher order of the component. For example, we might need to show some components when the user is logged in. To check this, you need to add the same code with each component. Here comes the use of the Higher-Order Component where the logic to check the user is logged in and keep your code under one app component. While the other components are wrapped inside this.

2. React Component Best Practices

Its components are the building blocks of a react project. Here are some of the React best practices that can be considered while coding with React in the component state and component hierarchy.

1. Decompose into Small Components

Try to decompose large components into small components such that each component performs one function as much as possible. It becomes easier for the development team to manage, test, reuse and create smaller components. 

Depending upon the project, one can split / decompose the design into smaller components in multiple ways: 

1. Programming: 

Use Single Responsibility Principle (SRP). One component should have only one functionality. If it ends up growing, then decompose that component into smaller subcomponents. 

2. Design: 

According to the design layers, you can decompose the components. 

2. Use Functional or Class Components based on Requirement

If you need to show User Interface without performing any logic or state change, use functional components in place of class components as functional components are more efficient in this case.

For instance:

  1. Try to minimize logic in React lifecycle methods like componentDidMount(), componentDidUpdate() etc. cannot be used with functional components, but can be used with Class components.
  2. While using functional components, you lose control over the render process. It means with a small change in component, the functional component always re-renders.

3. Use Functional Components with Hooks

After the release of React v16.08, it’s possible to develop function components with the state with the new feature ‘React Hooks’. It reduces the complexity of managing states in Class components. So always prefer to use functional components with React Hooks like useEffect(), useState() etc. This will allow you to repeatedly use facts and logic without much modification in the hierarchical cycle.

4. Appropriate Naming and Destructuring Props

To keep readable and clean code, use meaningful and short names for props of the component. Also, use props destructuring feature of function which discards the need to write props with each property name and can be used as it is.

Herewith props destructuring, we can directly use name and title without using props.name or props.title.

5. Use propTypes for Type Checking and Preventing Errors

It is a good practice to do type checking for props passed to a component which can help in preventing bugs. Please refer below code for how to use

React.PropTypes:

3. React Code Structure Best Practices

React does not have opinions on how you can write a better and less complex code but the following are some of the best approaches you may consider to improve the overall code structure.

1. Naming Conventions

  • A component name should always be in a Pascal case like ‘SelectButton’, ’Dashboard’ etc. Using Pascal case for components differentiate it from default JSX element tags.
  • Methods/functions defined inside components should be in Camel case like ‘getApplicationData()’, ‘showText()’ etc.
  • For globally used Constant fields in the application, try to use capital letters only. Like const PI = “3.14”;

2. Avoid the Use of the State as much as Possible

Whenever using state in the component, keep it centralized to that component and pass it down in the component tree as props.

3. Write DRY Code

Try to avoid duplicate code and create a common component to perform the repetitive task to maintain the DRY (Don’t Repeat Yourself) code structure.

For instance: When you need to show multiple buttons on a screen then you can create a common button component and use it rather than writing markup for each button.

4. Try to Avoid Unnecessary Div

  • When there is a single component to be returned, there is no need to use <div>.
  • When there are multiple components to be returned, use or in shorthand form <> as shown below:

5. Remove Unnecessary Comments from the Code

Add comments only where it’s required so that you do not get confused while changing code at a later time.

Also don’t forget to remove statements like Console.log, debugger, unused commented code.

6. Use Destructuring to Get Props

Destructuring was introduced in ES6. This type of feature in the javascript function allows you to easily extract the form data and assign your variables from the object or array. Also, destructuring props make code cleaner and easier to read.

For example:

  • Example 1:
    There is an objecting employee.

    To access properties of object, you need to write:

    Which can be written as following with destructuring:

  • Example 2:
    Let’s take another example. Take an example of a cat that we want to display as a div by naming a class and its type. In between the div, we can see a statement which will tell the cat’s color, its nature-good or bad, etc.

    To maintain clarity with the codes, we can put all the ternary operators in its own variable and see the change.

7. Apply ES6 Spread Function

It would be a more easy and productive way to use ES6 functions to pass an object property. Using {…props} between the open and close tag will automatically insert all the props of the object.

You can use the spread function:

  • There are no ternary operators required
  • There is no need to pass only HTML tag attributes and content

In case of repetitive use of functions, Don’t use the spread function when:

  • There are dynamic properties
  • There is a need for array or object properties
  • In the case of render where nested tags are required

8. The Rule of 3

When there are three or fewer properties, then you should keep those properties in their line inside both the component and the render function.

For example: It would be fine in the code below to write one line to get properties.

But, find the below code where more than 3 props are written in single line:

And in render

The above code becomes unreadable and clumsy. So when there are more than 3 props, write each one in a new line as below :

And in render

9. Manage too Many Props with Parent/Child Component

It’s a tricky task to manage properties at any level in components, but with the help of React’s state and ES6 destructuring feature, props can be written in a better way as shown below.

For example:
Let’s create an application having a list of saved addresses and GPS coordinates of the current location.

The current user’s location should be added in the favorite address and can be kept in parent component App section as shown below:

Now, to get data on how close current users are to the favorite address, we will pass at least two props from the App

In render() method of App:

In the render() for FavAddress Component:

As you can see in the above infographic, it’s getting unwieldy. It is more feasible to keep multiple sets of options and separate them within their own internal objects.

So, in App constructor:

At a point before App render():

In App render():

For the FavAddress Component, inside the render function we can see:

10. Use Map Function for Dynamic Rendering of Arrays

In react, it is possible to create an object with props that return a dynamic HTML block without writing repeated code. For this, react provides a map() function to display arrays in order. While using an array with a map(), one parameter from the array can be used as a key.

Apart from this, ES6 spread functions can be used to send a whole list of parameters in an object by using Object.keys().

Another example of mapping array is as follow:

11. Dynamic Rendering with && and the Ternary Operator

In React, it is possible to perform conditional renderings the same as a variable declaration. For small code with conditions, it’s easy to use ternary operators but with large code blocks, it becomes difficult to find those ternary operators. So the code can be written as below too:

The above way of conditional rendering will be useful when there are more than 2 conditions or we need to render some code on a specific condition and there is no else part. In those cases, you can use && operators with the condition.
So the above code can be written in true ternary fashion:

Even though the above code is well organized, it could have become messy and unreadable if the render function had more than just one line as there would be more nested brackets.

As you can see, in both cases code length is the same but there is one main difference, in the first example, there is rapid switching between two different syntaxes making visual parsing difficult as compared to the second, which is simple JavaScript code with variable assignments and one line return function.
It can be inferred from the above code that if the JavaScript is kept inside a JSX object is more than two words (e.g. object. property), then keep that code before the return call.

12. Use es-lint or Prettier for Formatting

Follow the es-lint rules while writing code and use line breaks wherever required for a clean and formatted code. You can also use prettier for formatting the code.

13. Write Tests for Each Component

It is a good practice to write test cases for each component developed as it reduces the chances of getting errors when code is deployed. With the unit testing, you can check all the possible scenarios. Jest or enzymes are the most commonly used react test frameworks.

14. Make Use of a Linter

The quality of the code may be enhanced with the aid of a linter. ESlint is among the most widely used linter tools for JavaScript and React. 

Stability in a codebase is also aided by a linter tool. The instrument keeps an eye on your code and alerts you if a predefined standard is breached. Often, the offending phrase or sentence would be highlighted in red.

Linter tools help developers to quickly correct the issues in the current code. Spelling mistakes, stated but unused variables, and other similar features are readily apparent. The good news is that some of these mistakes can be corrected on the fly while you write your code.

So, utilize linter tools for code quality parameters and Prettier for code formatting.

4. React Security Best Practices

Manytimes, it happens that developers conclude React will protect the entire code from all possible threats. But this is not always correct. React is considered a quite secure framework compared with other front-end frameworks, but still there are some practices to take into account while looking at the security part. Let’s look at some of the React security best practices to consider while developing any application:

1. Add Security to HTTP Authentication

There are multiple applications where authentication is done on user login or account creation and this process should be secure as the client-side authentication and authorization can be exposed to many security defects that may destroy these protocols in the application.

The commonly used technique for adding authenticity can be validated using.

  1. JSON Web Token (JWT)
  2. OAuth
  3. AuthO
  4. React Router
  5. PassportJs

Security with JWT
There are some points that to be taken into account while using JWT:

  1. Please avoid keeping JWT tokens based on Local Storage. As it would be very easy for someone to get a token using the browser’s Dev tools console and write.
    console.log(localStorage.getItem(‘token’))
  2. Store your tokens to an HTTP cookie rather than localStorage.
  3. Or, you can keep your tokens to your React app’s state.
  4. Tokens should be kept in the backend. It would be easy to sign and verify these keys at the backend side.
  5. You should use long and unpredictable secrets similar to the passwords field while creating an account asking for a strong and long password.
  6. Always make sure you use HTTPS in place of HTTP. This will give assurance for your web-based app to provide a valid certificate that can be sent over a secure SSL network.

2. Secure Against Broken Authentication

Sometimes when you enter authentication details, and the application crashes which might lead to exploitation of user credentials. So to remove this kind of vulnerability, make sure you follow the measures mentioned below.

  1. Do use multi-factor and 2-step authorization.
  2. You can use cloud-based authentication (for instance Cognito) for secure access.

3. Broken Access Control

With the improper management of restrictions and limitations on authenticated users can cause exploitation of unauthorized data and functionality of a React native app. Sometimes unauthorized users can also change the primary key of data and manipulate the functionality of the application. To ensure security from unauthorized access, follow these practices:

  1. Add a role-based authentication mechanism to your react code
  2. To secure your application, deny functionality access

4. Cross-Site Scripting (XSS)

  1. You can create automated overseeing features that can sanitize the user input
  2. Discard malicious and invalid user input from being rendered into the browser.

5. Secure Against DDoS Attacks

The vulnerable security concerns take place when the whole application state management  has loopholes and it masks the IPs. This will restrict the communication caused due to the termination of services. Here are some methods to stop this:

  1. Limitation of rate on APIs- This will add limitations to the number of requests for a given IP from a specific source with a complete set of libraries using the Axios-rate limit.
  2. Add app-level restrictions to the API.

6. SQL Injection

This attack is related to data manipulation. Due to this vulnerability, attackers can modify any data with or without the user’s permission or can extract any confidential data by executing arbitrary SQL code.

Solution

  1. To eliminate SQL injection attacks, first, validate API call functions against the respective API schemas. In order to handle the issue of time-based SQL injection attacks, you can use timely validation of the schema to avoid any suspicious code injections
  2. Another effective way to secure against the SQL vulnerability is by using an SSL Certificate.

7. Using dangerouslySetInnerHTML

In React, you can use ‘innerHTML’ for an element inside DOM which is a risky practice as it’s a wide-open gate for XSS attack. So to remove this issue, React has provided a “dangerouslySetInnerHTML” prop to safeguard against this type of attack.

Also, you can use libraries such as DOMPurify in order to sanitize user input and remove any malicious inputs. React already has an inbuilt function called dependency injection for properly managing user interfaces.

8. Stay Up to Date With React Version Changes

Keeping an eye on the official version can help you to improve the security features and remove the possible vulnerability present in the current code. 

You should likewise be familiar with the external libraries that have been developed for React, such as React Router(a routing library). Understanding the specifics of the modifications made by these libraries will allow you to streamline the development process for your app.

5. Conclusion

With this blog, we gave you a deeper insight into both reactjs developer and frontend developer on how ReactJS works, how to add security, how to build components and applications. The ReactJS best practices will offer you fewer typing options and more explicit codes. Once you will start using this, you will start liking its clear crisp features with code reusability, advanced react components, adding a separate state variable, and other smaller ready-made React.js features for simplified use. This list of best practices from React will help you place your ventures on the right path, and later down the line, eliminate any future development complications.

We have presented an info-graphical representation of ReactJS Best Practices. Take a look:

Want to embed this image? Please cite source to TatvaSoft.com

Share this Image On Your Site

Please include attribution to TatvaSoft.com with this graphic.
<a href="https://www.tatvasoft.com/blog/reactjs-best-practices/"><img src="https://www.tatvasoft.com/blog/wp-content/uploads/2021/03/ReactJS-Infographic-1.jpg" alt="React Best Practices" width="952" height="3948"></a>

Other Best Practices Blogs:

  1. Angular Best Practices and Security
  2. NodeJS Best Practices and Security
  3. VueJS Best Practices and Security
  4. QA Best Practices for Software Testing
  5. DevOps Best Practices
  6. SharePoint Best Practices
  7. .NET Core Best Practices

Comments


Your comment is awaiting moderation.

View Comments

  • There is a best practice that I would like to suggest to all React developers, it is making use of Linter. It helps in keeping the code free from errors and also helps in detecting bugs as well.

  • One rule that is applicable to all developers is that the code that you’re writing should act as expected and should also have the testable quality as well. For decreasing the testing time and to improve productivity it is better to name the test file as similar to source files with a postfix of .tested.

  • Jest is one of the favorite testing tool for React app. The benefits that this framework offers are, it is simple to learn, there is no setup cost and also helps to manage large test cases easily.

  • One of the many problem that developers generally face is keeping track of a lot of data on the React app they are developing. This happens because of React State, it keeps the track of data when changes take place in your app. So the best practice is to avoid using React State to the extent possible and declaring it only when needed.

  • For any development process on wards and afterwards, Testing is the most crucial part of the process which cannot be left. For any junior developer performing testing is sometimes an irritating task because they're still in the learning stage and getting continuous errors will give them a headache.

  • One of the best practices that I can suggest is making use of tools like Bit. Bit can help in maintaining and reusing the code, improves the team's joint efforts, and also helps in code discovery.

    • In a larger project What happens is Styling and theming tasks are challenging activities and maintaining these big CSS files can add up more to this challenge. So the concept of CSS-in JS solutions was introduced. EmotionJS, Styled Components, Glamorous are some of the libraries based on this concept.

  • I would like to add something to EmotionJS- it is a JavaScript library that allows you to write CSS styles in JavaScript language. It's small and light, with the ability to deliver high-end performance.

  • Thank you very much for this. I am already heckled with lots of project in react and was searching for some good resources to execute the projects. Stumbled on this piece and will implement certain things on my project and will leave feedback.
    reply

  • Here JSX stands for JavaScript XML (eXtensible Markup Language) it is an extension of ReactJS environment. To put that another way, JSX makes it easier for developers to write and add HTML code to React.