DEV Community

Mayank Tamrkar
Mayank Tamrkar

Posted on

12 React Best Practices Every Developer Should Know

Boost Your React Skills with These 12 Best Practices .

1 Use Ternary Operator for Conditional Rendering:

import React from 'react';

const MyComponent = ({ isLoggedIn }) => {
  return (
    <div>
      {isLoggedIn ? <p>Welcome, User!</p> : <p>Please login.</p>}
    </div>
  );
};

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

2 Use JSX Spread Attributes for Props:

Using spread attributes is generally preferred as it makes the code cleaner and more maintainable, but it's essential to ensure that only necessary props are passed down to avoid unnecessary re-renders or potential bugs.

Example without spread attributes:

import React from 'react';

const MyComponentWithoutSpread = (props) => {
  return <ChildComponent prop1={props.prop1} prop2={props.prop2} />;
};

export default MyComponentWithoutSpread;
Enter fullscreen mode Exit fullscreen mode

Example with spread attributes:

import React from 'react';

const MyComponentWithSpread = (props) => {
  return <ChildComponent {...props} />;
};

export default MyComponentWithSpread;
Enter fullscreen mode Exit fullscreen mode

3 Use Fragment to Return Multiple Elements:

When returning multiple elements, use Fragment or shorthand syntax (<>...</>).

import React from 'react';

const MyComponent = () => {
  return (
    <>
      <h1>Title</h1>
      <p>Content</p>
    </>
  );
};

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

4 Keep Component State Local:

Keeping component state local ensures that each component manages its own state independently for better encapsulation and easier maintenance.

import React, { useState } from 'react';

const Parent = () => {
  return (
    <div>
      <Child />
      <Child />
    </div>
  );
};

const Child = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Parent;
Enter fullscreen mode Exit fullscreen mode

5 Use Memoization for Performance Optimization:

Memoization optimizes performance by caching expensive function results, reducing unnecessary recalculations and rendering in components for faster applications.

import React, { useMemo } from 'react';

const ExpensiveComponent = ({ num }) => {
  const computedValue = useMemo(() => {
    // Expensive computation
    return num * 2;
  }, [num]);

  return <div>{computedValue}</div>;
};

export default React.memo(ExpensiveComponent);
Enter fullscreen mode Exit fullscreen mode

6 Use Custom Hooks to Encapsulate Logic:

Using custom hooks in React encapsulates and reuses stateful logic across components, improving code reuse, organization, testing, and readability, making it a best practice for maintainable and clean code.

import { useState, useEffect } from 'react';

const useFetchData = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
};

const DataDisplay = ({ url }) => {
  const { data, loading } = useFetchData(url);

  if (loading) return <p>Loading...</p>;

  return <pre>{JSON.stringify(data, null, 2)}</pre>;
};

export default DataDisplay;
Enter fullscreen mode Exit fullscreen mode

7 Avoid Inline Functions in JSX:

Avoid inline functions in JSX because they create new function instances on every render, which can hurt performance. Instead, define functions outside JSX to improve efficiency and prevent unnecessary re-renders.

const Button = ({ onClick }) => (
  <button onClick={onClick}>Click me</button>
);

const App = () => {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return <Button onClick={handleClick} />;
};

export default App;
Enter fullscreen mode Exit fullscreen mode

8 Passing Default Props:

Passing default props ensures that your component has a fallback value if a prop is not provided. This enhances component reliability by preventing errors due to missing props and simplifies the component logic by reducing the need for explicit checks or conditional rendering within the component itself.

function Avatar({ person, size = 100 }) {
 // ...
}
Enter fullscreen mode Exit fullscreen mode

9 Use Component Composition:

Component composition in React means building complex components by combining simpler, reusable components for better maintainability and readability.

const Header = ({ title }) => <h1>{title}</h1>;

const Content = ({ children }) => <div>{children}</div>;

const App = () => (
  <div>
    <Header title="Welcome to My App" />
    <Content>
      <p>This is the content of the app.</p>
    </Content>
  </div>
);

export default App;
Enter fullscreen mode Exit fullscreen mode

10 Use Cleanup Function in useEffect:

Cleanup function in useEffect ensures proper resource cleanup, preventing memory leaks and maintaining component cleanliness.

import React, { useState, useEffect } from 'react';

const Timer = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCount(count => count + 1);
    }, 1000);

    // Cleanup function
    return () => clearInterval(interval);
  }, []); // Empty dependency array for componentDidMount behavior

  return <div>Timer: {count}</div>;
};

export default Timer;
Enter fullscreen mode Exit fullscreen mode

11 Use Error Boundary:

Using error boundaries helps to catch and handle errors in React components, providing better user experience, preventing crashes, and improving application robustness, making it a best practice for error management.

import React, { useState, useEffect } from 'react';

const ErrorFallback = () => (
  <div>
    <h2>Something went wrong!</h2>
    <p>Please try again later.</p>
  </div>
);

const ErrorBoundary = ({ children }) => {
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    const handleError = (error, errorInfo) => {
      console.error('Error caught by Error Boundary:', error, errorInfo);
      setHasError(true);
    };

    // Return
Enter fullscreen mode Exit fullscreen mode

12 Lazy Load Components

Lazy loading components helps to improve the performance of your React application by loading components only when they are needed. This can reduce the initial load time of your application.

   import React, { Suspense, lazy } from 'react';

   const LazyComponent = lazy(() => import('./LazyComponent'));

   const App = () => {
     return (
       <div>
         <h1>My App</h1>
         <Suspense fallback={<div>Loading...</div>}>
           <LazyComponent />
         </Suspense>
       </div>
     );
   };

   export default App;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)