Before writing code for a particular design of a page or a project. The first step should be planning what components you will create in this particular page or a feature. Determine their name and write it down somewhere. To name the components you can discuss with your peers. The Component names should be in PascalCase . Once you have listed them down it's time to separate them into two categories Atomic components and Non-atomic Components. Atomic Components are the one's which they make up the UI library of the project.They become the foundation of Non-atomic Components. Non Atomic Components are created by composing Atomic Components together. Example of atomic components could be Input, Card, Column, Button,Heading, Popup, Tooltip, etc. Non Atomic Component could be a particular section of page, Sidebar with widgets, etc.
Example of Component Plan
The above image is a screenshot of a section. The main Component is the whole section called FeatureSection which has the following child components :
HeadingWithInfo (Non-atomic)
Card (Atomic)
CardImage (Atomic)
CardTitle (Atomic)
Paragraph (Atomic)
H1 (Atomic)
Info (Atomic)
Prop Planning
Prop planning means planning the name and type of props a component will have . Lets take the example of Above HeadingWithInfo Component. This component can have two props named info and title and both of these props will be of type string. Lets make the prop specification of the above mentioned components.
StyleProps here refers to Common Styling Props that could be useful in overriding the Atomic component in some places.
HeadingWithInfo
title: string
info: string
Card
children: React.ReactNode
...StyleProps
CardImage
src: string
alt: string
...StyleProps
CardTitle
children: React.ReactNode
...StyleProps
Paragraph
children: React.ReactNode
...StyleProps
State Planning
State Planning refers to the state variables that you need in order to create the component. And in which component the state will be located in the component tree.
Basic Rules
Always use Typescript
Only One Component Per File
Follow Don't Repeat Yourself (DRY) principle
Code should always be formatted before being pushed to Github, or any other repo
Always prefer function components (vs class components)
use Arrow functions everywhere unless it is absolutely necessary.
TypeScript
Don’t use defaultProps. You can set object default values.
Imports
Points to remember when importing components from external libs or iternally.
Imports of components should be properly formatted.
//bad
import React, { useEffect,
useState } from "react";
// good
import React, { useEffect, useState } from "react";
// bad
import cardImage from "./CardImage";
// good
import CardImage from "./CardImage";
// good
import axios from "axios";
// bad
import Footer from "./Footer/Footer";
// bad
import Footer from "./Footer/index";
// good
import Footer from "./Footer";
Props
Always use CamelCase for Props
// bad
<Foo
UserName="hello"
phone_number={12345678}
/>
// good
<Foo
userName="hello"
phoneNumber={12345678}
Component={SomeComponent}
/>
Avoid adding Extra Braces inside props.
// bad
<Card hidden={true} />
// good
<Card hidden />
// bad
<Card title={"Awesome Title"} />
// bad
<Card title={ "Awesome Title" } />
// good
<Card title="Awesome Title" />
if writing conditional classes use clsx library to join their names.
Limit number of props to a component max of 6 props. More than 6 props should have a valid reason.
State
Max number of recommended useState hooks that should be used is 4. If you need more state variables. Either move the state to useReducer hook or move it to store.
State variables names should be meaningful, simple and easy to understand their meaning.
Hooks
Ordering is very important while writing standardized code
Ordering means ordering various hooks or parts inside the source code of components. Following order should be followed while writing source code of components:
useState Hook
useReducer Hook
useContext Hook
useRef Hook
external library hooks
useSelector
useDispatch
useActions, etc
useMemo Hook
useCallback Hook
Any event handlers like handleSubmit, handleClick, etc
useImperativeHandle Hook
useLayoutEffect
useEffect
methods return Jsx like renderContent, renderPopup, etc
After that you will write the return statement which returns jsx of the component.
Instead of using Refs directly by assigning or reading ref.current property of ref, create getter and setter functions for ref called getRef and setRef.