React

Best Practices 


Framework

There are multiple frameworks available in the React but we need to use popular and matured one NextJS.

There are multiple reasons to use NextJS

  1. Server Side Rendering (SSR)
  2. SEO benefits
  3. Reduce server load and Improved processing speed
  4. Automatic code splitting
  5. Hot reloading
  6. Custom Routing
  7. Support of multiple libraries
  8. Customization in server behavior

 

NEXT.js Project Structure Need to follow

Organize files by feature rather than by type. This makes it easier to manage and scale the project. my-next-app/

├── .next/

├── node_modules/

├── public/

│ ├── images/

│ ├── favicon.ico

│ └── ...

├── src/

│ ├── components/

│ │ ├── Header.js

│ │ └── Footer.js

│ ├── pages/

│ │ ├── api/

│ │ │ └── hello.js

│ │ ├── _app.js

│ │ ├── _document.js

│ │ ├── index.js

│ │ └── about.js

│ ├── styles/

│ │ ├── globals.css

│ │ └── Home.module.css

│ ├── utils/

│ │ └── helper.js

│ ├── hooks/

│ │ └── useAuth.js

│ └── context/

│ └── AuthContext.js

├── .gitignore

├── package.json

├── README.md

└── next.config.js

 Project Structure

1. .next/

Automatically generated when you build your project. Do not touch this folder.

2. node_modules/

Contains all the packages installed via the package manager.

3. public/

This directory is used to store static files such as images, fonts, and other assets.

4. src/

A common convention to place your application code here for better organization.

    • components/: Contains reusable React components.
    • pages/: Each file in this folder represents a route in your application. The api/ subfolder is used for API routes.
      • _app.js: Customizes the default App component, allowing you to override it to control page initialization.

      • _document.js: Customizes the default Document component, useful for augmenting the application's HTML and body tags.

      • index.js: Represents the homepage of your application.

      • Additional files like about.js represent other routes/pages.styles/: Contains global and component-specific styles.
    • styles/: Contains global and component-specific styles.
        • globals.css: Global CSS file that affects the entire application. You can also use a SCSS file.
        • Home.module.css: Example of a CSS module for component-specific styles.
    • utils/: Utility functions and helpers.
    • hooks/: Custom React hooks.
    • context/: React context providers.

5. .gitignore

Specifies files and directories that should be ignored by Git.

6. package.json

Contains metadata about the project and its dependencies.

7. README.md

Project documentation.

8. next.config.js

Configuration file for customizing the behavior of the Next.js application.

Environment Variables

1. .env Files

Store environment variables in .env.development, .env.stage, and .env.production files.

2. All the .env files are strictly added in the GIT IGNORE file.

3. In NextJS, env variables beginning with NEXT_PUBLIC are available at client side as well. So before naming a variable with NEXT_PUBLIC make sure whether this env variable will be needed on the client side or not.

Component Design Rules

Break down your application into small, reusable components.

  1. Reusable Components: Create reusable components to avoid duplication. create one folder called `features` modules wise you can create separate components in that.
  2. HOC (Higher order components): Reuse components logic to multiple components.
  3. Single Responsibility: Each component should have a single responsibility.
  4. Component types: Prefer to use functional components with hooks for state management and side effects. This approach is more aligned with the future direction of React.

class components are still relevant, especially when specific lifecycle methods or error boundaries are necessary. 

As React developers, being comfortable with both functional and class components is essential. While the trend is moving towards functional components, there are still scenarios where class components are the right choice hence you need to use based on your requirements.

 

If you see that your component is becoming too big try to break it down into smaller components. Keep your components lightweight i.e., they must mostly deal with rendering the view part (JSX / HTML) or the app. Lightweight logic can be kept in the component but try to move complex state logic into a custom hook, even though it may seem that this hook is used only at a single place.

Choose Rendering pattern based on your web page need

Client side rendering (CSR): 

  • Ideal for highly interactive single page apps, internal tools, and applications where SEO is not a priority. 
  • Use getStaticProps for fetching data at build time for static pages.

Server side rendering (SSR): 

  • Best for applications where SEO and fast initial load times are important, such as e-commerce sites and marketing pages.
  • Use getServerSideProps for fetching data on each request.

Best Practices for Routes

  1. Organize by Feature or Domain: Group related pages and API routes by feature or domain for better organization.
  2. Use clear and consistent naming conventions of files and directories for SEO friendly.
  3. Use dynamic routes (HIGHLY RECOMMENDED).
  4. API Middleware: Run before your route handlers and can modify the incoming requests or outgoing responses. They are useful for code that needs to run repeatedly across multiple routes, such as authentication checks, logging, or setting response headers.
  5. Use an Axios interceptor. Avoid using multiple fetch requests.
  6. Error handling in API routes: Manage common error handling for each routes.

Security Best Practices for routes

  1. Validate and Sanitize Inputs: Always validate and sanitize incoming data to prevent common vulnerabilities such as SQL injection and cross-site scripting (XSS). Use libraries like joi or express-validator to validate data as it comes into your API endpoints.
  2. Implement Rate Limiting: Prevent abuse and denial-of-service attacks by limiting the number of requests users can make to your API endpoints. Next.js does not include built-in rate limiting, so consider using third-party libraries like express-rate-limit.
  3. Use Secure Headers: Set HTTP headers to secure your API against common attacks. Use packages like helmet to automatically set headers that enforce secure connections and restrict XSS attacks.
  • Use TypeScript, ensure your routes are typed correctly to catch errors early.

Dependency Management

  1. Keep Dependencies Updated: Regularly update packages, React and Next version to benefit from the latest features and security fixes.
  2. Minimize the use of External Libraries/Packages: You have to use a minimum number of packages and third party dependencies it will help us to bundle size manageable.
  3. Get a thorough idea about popular packages before using. Some popular packages in the React ecosystem are, Redux, material-ui, react-router-dom, tanstack/react-table, tanstack/react-query, etc. These are some of the very popular packages and it is important that we learn how to use them properly, because if we use them in an incorrect manner that might create problems later on.

Best Practices for creating hooks

  1. React provides several built-in hooks like useState, useEffect, useMemo and useCallback. You have to use it for your projects whenever needed.
  2. When needed you need to create Custom hooks that leverage these built-in hooks to encapsulate and reuse logic across components.
  3. Use the “use” prefix: This clearly indicates that a function is a hook. For example, useFetchData, useForm, useAuthentication.
  4. Use try-catch blocks: Protect your hook from unexpected errors.
  5. Single Responsibility: Each hook should do one thing well. If a hook is doing too many things, consider breaking it into smaller hooks.
  6. Parameterization: Make hooks configurable through parameters to increase reusability.

Best practices for the state management

1. Keep State as Local as Possible

Minimize the use of global or shared state.

2. When setting and updating state based on the current local state then used setState, useState, useReducer

3. For sharing state across multiple components and to manage complex state, use React's Context API.

4. If you want to introduce global state then you have to use any one from popular state management external libraries like Redux, Zustand, or Recoil.

5. Do not use multiple state management libraries in a project. It will impact the speed and performance.

6. Server-Side State Management

For server-side state management, leverage Next.js's data fetching methods (getServerSideProps, getStaticProps, and getStaticPaths).

Best practices for the props

1. Consistent Naming Conventions

Use consistent naming for props.

2. Prop Validations

Use TypeScript with using  interfaces or type aliases to enforce prop types and validations.

3. Avoid Unnecessary Props

Pass only the props that are necessary. It will increase the speed

4. Use default props for optional props to ensure components always have default values and avoid undefined errors.

Avoid unnecessary re-renders to increase the speed.

Setup unit tests in the project

Using react-testing-library to write unit tests for each component.

Other points

  1. When we load an image or script tag with using next js then next js tags should be used. if you have static images better to use SVG, code in one file exporting components.
  2. Dynamic Metadata: Use generateMetadata to create dynamic metadata based on page content or parameters.
  3. Use the Image component to improve image optimization.
  4. productionBrowserSourceMaps: false, by default its false in production
  5.  

0