React JS Coding Standards
Basicsβ
Responsiveβ
Always ensure that all pages of the website look, work and feel perfectly on any device
How to achieve responsive design ?β
Responsive layouts in Material Design adapt to any possible screen size. We provide the following helpers to make the UI responsive:
- Grid: The Material Design responsive layout grid adapts to screen size and orientation, ensuring consistency across layouts.
- Container: The container centers your content horizontally. It's the most basic layout element.
- Breakpoints: API that enables the use of breakpoints in a wide variety of contexts.
- useMediaQuery: This is a CSS media query hook for React. It listens for matches to a CSS media query.
README.mdβ
Your app should contain a proper README.md file that clearly details or explains your app. Clearly mention the features, functionalities, contributions guidelines, installation process, guide, etc.
Every readme should cover at least the following:
- A description of what the project is about
- How it looks (screenshots π·, gifs, etc.)
- Instructions on how to run or use itπ¨βπ»
- Should contain other relevant details (code samples, tech framework, credits, etc.)
Folder Structureβ
Group all realated files in one folder.
src/
βββ assets/
βββ components/
βββ contexts/
βββ font/
βββ graphql/
βββ HOCs/
βββ networkcall/
βββ redux/
βββ screens/
βββ themes/
βββ utils/
βββ App.alert.js
βββ App.auth.js
βββ App.backdrop.js
βββ App.dialog.js
βββ App.drawer.js
βββ App.errorBoundry.js
βββ App.gqlclient.js
βββ App.js
βββ App.logger.js
βββ App.test.js
βββ App.theme.js
βββ config.js
βββ i18n.js
βββ index.css
βββ index.js
/assets
: Collection of SVG asset functional components used all over the app./components
: Collection of all components and all the components need to be exposed via index.js only./contexts
: Collection of all Contexts used all over the app./font
: Where the font used in the application is saved./graphql
: Graphql Setups,index.js
contain the client setup,queries.js,mutation.js and subscription.js
contains the graphql quries used in the application./HOCs
: Collection of all HOC's used in the app. It is recommended to define all the HOC's here./networkcall
: It contains the function which is used for all the network call. i.e To hit API it check : Internet Connection, Proper URL, Proper Payload before the network call. We use Axios for all the network call./routers
: It contains theindex.js
file where all the routing are defined. Theroute.js
file contain all the routes used all over the application. Theprivate_router.js
contains the private router for protected routes. Finallyaccess.js
contains functions that define the different routes for different roles used in the application./screens
: It contain all the screens (typically all the components are built togethere here) in the app is defined here./themes
: Contains all the Theme JSON's (default.json,darktheme.json) we want to use the thoroughout the app. Use this Material UI Theme Generator for creating new themes./utils
: All the common functions,constants are defined in theindex.js
of the folder.
Code Structureβ
- Put all your imports in order at the very top of the code file. You shall ideally prioritize as follows:
import React, { useState, useEffect, useCallback } from "react";
import Typography from "@material-ui/core/Typography";
import Divider from "@material-ui/core/Divider";
Make sure all your imports statements are on new lines, as this will make your imports clean and easy to understand for all the components, third-party libraries, etc. Treat props as read-only. Do not try to modify them.
- Use index.js for each folder to export so that all the imports are referenced on the index.js file, and you don't have to write import statements again and again for every file.
import ActiveNews from "./ActiveNews";
import HistoryNews from "./HistoryNews";
import News from "./News";
export { ActiveNews, HistoryNews, News};
It's easy to get confused about whether to use double quotes (" ") or single quotes (' ') while working with react. The simple answer is: maintain consistency whatever you're using. Also, consider that you use double quotes (" ") for jsx attributes and single quotes (' ') for the js code (follow the standard way or maintain consistency).
Dividing the whole app into components and then working on it on a separate file is a good practice to maintain clean code.
Place all your css files in one common folder.
Do you sometimes use CSS styles with JSX? But it's a bad practice. Always make classNames for each element and put all the styling under respective CSS files only.
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles({
subheader: {
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
},
});
export default useStyles;
import React from 'react';
import useStyles from '../Subheader/Subheader.styles.js';
export default function Subheader() {
const classes = useStyles();
return (
<div className={ classes.subheaderContainer }>
<div className={ classes. subheader } >
</div>
</div>
</div>
)}
Create many utility files that can help you remove duplicate code from multiple files.
Create multiple files instead of writing a big file. (Componentization of code: fix to small functionality for each file)
Separate all your service calls into a separate file. If itβs a big project, try to split the services into multiple files. (name convention module_name.service.js).
Name your files logically according to the job that they perform.
Clean code is self-commenting (using the right variable names and function names). Use comments only to explain complex functions.
Use the dry principle (don't repeat yourself).
Use higher order components where appropriate.
Only include one react component per file.
Remove console. Logs β unless you have strong motivation why you would like it.
Avoid multiple if-else blocks. Instead, use ternary β best for clean code practice
Remove all commented-out codes. The biggest motivation for writing comments is the bad code that you write. It would be good to spend more time writing descriptive functions, methods, and filenames that are self-explanatory.
Write comments that are legal, informative, explanatory of intent, and offer clarification,
Naming Conventionsβ
- Componentβs names should be written using PascalCase
Header.js
HeroBanner.js
CookieBanner.js
- Non-components should be written using camelCase
myUtilityFile.js
cookieHelper.js
fetchApi.js
- Inline Styles Should Be camelCase
<div style={{font-size:'1rem'}}></div>
- Attribute name should be camelCase
className
onClick
- Variable names should be camelCase. Variable names can contain number and special characters
const variable = 'test';
let variableBoolean = true;
- CSS files should be named the same as the component
CookieBanner.css
Header.css
Bug Avoidanceβ
Optional Chaining and Nullish Coalescingβ
Start Using Optional Chaining and Nullish Coalescing in React.
When developing in JavaScript, you often need to access deeply-nested properties from tree-like structures. The common solution is to write a long chain of property accesses. The problem is that if any of the intermediate references in the chain is null or undefined, JavaScript will throw a TypeError: Cannot read property βnameβ of undefined error.
So, you may end up writing custom logic to avoid this from happening. Not only is this code ugly, but it also makes your codebase less readable. This is why the optional chaining operator was introduced.
obj.val?.prop // default use
obj.val?.[expr] // optional chaining with expressions
obj.arr?.[index] // array item access with optional chaining
obj.func?.(args) // optional chaining with function calls
let value;
let defaultValue = value || 'Hello World!';
Propsβ
Treat Props as Read-Only. Do Not Try to Modify Them.
- Props is a special keyword in React, which stands for properties and is being used for passing data from one component to another.
- Props data is read-only, which means that data coming from the parent should not be changed by child components.
Stateβ
Avoid Mutating State When Working with Arrays. In React docs, Its mentioned that never change this.state directly instead always use this.setState for any state updates, these are two main reasons to do this:
setState works in batches, which means one cannot expect the setState to do the state update immediately, it is an asynchronous operation so the state changes may happen in later point in time which means manually mutating state may get overriden by setState.
Performance. When using pure component or shouldComponentUpdate, they will do a shallow compare using === operator, but if you mutate the state the object reference will still be the same so the comparison would fail.
Pure Functionsβ
Create Pure Function and Avoid Side Effects. Using pure functions is the easiest way in which you can reduce the cognitive load of understanding your code and make it simpler for other developers to get up to speed quickly.
Side Effectsβ
Side effects in programming occur when a function changes elements that are outside of its scope. Letβs look at an example of a function that produces side effects.
const names = ['Tommy', 'Mike', 'Anna']
const addName = newName => { names.push(newName)}
addName('David')
// names = ['Tommy', 'Mike', 'Anna', 'David']
As you can see after we execute the addName the underlying global variable names changes. The variable is not local to the addName, hence the function has created a side effect.
Pure Functionsβ
Letβs take a look at an example of a function that doesnβt produce any side effects.
const names = ['Tommy', 'Mike', 'Anna']
const addName = (newName, names)=> {
return [...names, newName]
}
const newNames = addName('David', names)
// newNames = ['Tommy', 'Mike', 'Anna', 'David']
We have changed the addName function by adding an extra argument and the internal code block in which the appending itself happens. Now the function doesnβt depend on any global variables. Weβre also not modifying any arguments passed in. Our function now creates a new array of the desired shape.
ES6β
- Always destructure your props. Destructuring your props helps make your code cleaner and more maintainable. It also makes assigning object properties to variables feels like much less of a chore. Treat Props as Read-Only. Do Not Try to Modify Them.
- Know where to use spread/rest operators. You shall read about it before using it.
- optional chain operator be used instead of an explicit null check.
- Use const instead of var or let . const lets you check that a variable should always stay constant. let indicates that the values of the variables can be changed.
- Start preferring arrow functions (= >) for more cleaner code. Arrow functions allow simplifying your code to a single line.
- Can nullish coalescing by used instead of a explicit null comparison.
Configuration (.env)β
If you are using some external APIs for data you must use the .env file to store your sensitive credentials like API keys. Environment variables can also help us to store our API link in one location so that we donβt have to change the link in each file manually.
Open the .env file and declare your environment variable.
REACT_APP_TITLE=Sample Title
REACT_APP_DESCRIPTION=Sample Description
REACT_APP_URL=βhttp://localhost:8080/β
- Now to print your environment variable you need to put process.env before your custom variable.
process.env.REACT_APP_TITLE
process.env.REACT_APP_DESCRIPTION
React Componentsβ
Class Componentβ
import React from "react";
class App extends React.Component {
constructor(props) {
super(props);
this.state = { change: true };
}
render() {
return (
<div>
<button
onClick={() => {
this.setState({ change: !this.state.change });
}}
>
Click Here!
</button>
{this.state.change ? (
<h1>Hello World </h1>
) : (
<h1>Welcome </h1>
)}
</div>
);
}
}
export default App
Functional Componentβ
import React, { useState } from 'react';
const Example= () => {
const [change, setChange] = useState(true);
return (
<div>
<button onClick = {() => setChange(!change)}>
Click Here!
</button>
{change?<h1>Hello World </h1>:
<h1>Welocome </h1>}
</div>
);
}
export default Example;