Skip to content

React Tips and Tricks for Efficient Development

React tips for writing clean, efficient components: avoiding wrapper elements, using useCallback, and simplifying conditional rendering.
GuideUpdated 4 min readDevelopmentReact Js

React Tips and Tricks for Efficient Development

None of what follows is a trick in the sense of being clever. They are the habits that separate a component someone else can pick up from one that has to be rewritten, and most of them cost nothing at the time and save a great deal later.

Insights: Why Efficient React Coding Matters

React is a powerful tool, but writing efficient code can make a big difference in your app’s performance and usability. Here’s why these best practices matter:

  • Better Performance: Optimised components render faster, improving user experience.
  • Easier Maintenance: Clean and consistent code is easier to update and debug.
  • Cost-Effective: Efficient code means shorter development times and fewer bugs.
  • Improved Accessibility: A streamlined DOM structure benefits all users.

React Best Practices and Tips

Avoid Multiple Wrapper Elements

Reduce unnecessary DOM nodes using React fragments (<> </>). This enhances performance and keeps your component tree clean.

// Bad Practice
function Layout() {
  return (
    <div>
      <header>Header</header>
      <main>Main Content</main>
    </div>
  );
}

// Good Practice
function Layout() {
  return (
    <>
      <header>Header</header>
      <main>Main Content</main>
    </>
  );
}
  • Reduces unnecessary DOM nodes
  • Improves rendering performance
  • Cleaner and more readable code

Simplify Conditional Rendering

Write concise and readable conditions using short-circuit operators (&&) and ternary operators.

Use Short-Circuiting (&&) for Simple Conditions:

// Bad Practice
{isLoggedIn ? <p>Welcome back!</p> : null}

// Good Practice
{isLoggedIn && <p>Welcome back!</p>}

Use Ternary Operators for Dual Outcomes:

// Bad Practice
{isLoading ? (
  <p>Loading...</p>
) : (
  <p>Data loaded!</p>
)}

// Good Practice
<p>{isLoading ? "Loading..." : "Data loaded!"}</p>
  • Makes JSX more concise and readable
  • Reduces code duplication

Use Default Props

Ensure components have fallback values to prevent rendering issues.

function Greeting({ name = "Guest" }) {
  return <h1>Hello, {name}!</h1>;
}
  • Prevents unexpected undefined values
  • Simplifies component usage
  • Provides sensible defaults

Use Self-Closing Tags

Simplify your JSX syntax with self-closing tags for components without children.

// Bad Practice
<img src="logo.png"></img>

// Good Practice
<img src="logo.png" />
  • Reduces visual clutter in JSX
  • Prevents bugs from missing closing tags
  • Aligns with modern HTML practices

Use Key Props in Lists

Assign unique keys to list items to help React optimise re-rendering.

Avoid Using Index as Key (When Possible):

// Bad Practice
{items.map((item, index) => (
  <li key={index}>{item.name}</li>
))}

// Good Practice
{items.map(item => (
  <li key={item.id}>{item.name}</li>
))}
  • Improves rendering performance
  • Reduces bugs during reordering
  • Helps React identify which items changed

Use useCallback for Stable Functions

Optimise performance by preventing unnecessary re-renders with useCallback.

function ParentComponent() {
  const handleClick = () => {
    console.log("Clicked");
  };

  return <ChildComponent onClick={handleClick} />;
}
import { useCallback } from "react";

function ParentComponent() {
  const handleClick = useCallback(() => {
    console.log("Clicked");
  }, []);

  return <ChildComponent onClick={handleClick} />;
}
  • Improves performance in large applications
  • Prevents unnecessary re-renders of child components
  • Optimises memoised components ( React.memo )

Use export default for Main Components

Use export default for better code organisation and easier imports.

// Exporting
export default function Header() {
  return <h1>Header</h1>;
}

// Importing
import Header from './Header';
  • Easier to import components
  • Reduces confusion with multiple named exports
  • Simplifies file organisation

Avoid Inline Styles

Separate your styles from components using external CSS or styled-components.

// Bad Practice
<div style={{ color: 'red', fontSize: '20px' }}>Hello</div>

Use CSS Modules or Styled Components:

// Good Practice (CSS Module)
import styles from './Button.module.css';

function Button() {
  return <button className={styles.primary}>Click Me</button>;
}
import styled from 'styled-components';

const Button = styled.button`
  color: white;
  background-color: blue;
  font-size: 16px;
`;

function App() {
  return <Button>Styled Button</Button>;
}
  • Keeps JSX clean and focused on structure
  • Improves styling consistency
  • Allows style reuse and theming

Performance: Load Less, Render Less

The tips above keep code clean. These four keep a growing app fast.

Split Code with React.lazy and Suspense

Load a heavy component only when it is needed, instead of in the first bundle:

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

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

const App = () => {
    return (
        <Suspense fallback={<p>Loading component...</p>}>
            <HeavyComponent />
        </Suspense>
    );
};
export default App;

The same idea works per route: lazy-load each page so a visitor downloads only the page they open. Most routers and frameworks, Next.js included, split code by route for you.

Skip Re-renders with React.memo

React.memo re-renders a component only when its props change. It pairs with useCallback above: a memoised child is only skipped if the functions passed to it keep the same reference.

import React from 'react';

const Button = React.memo(({ onClick, label }) => {
    console.log("Rendering Button");
    return <button onClick={onClick}>{label}</button>;
});

export default Button;

Cache Expensive Values with useMemo

useMemo recalculates a value only when its dependencies change. Use it for genuinely expensive work such as filtering or sorting a large list, not for simple arithmetic, where the memoisation costs more than it saves. In short: useMemo caches a value, useCallback caches a function, and React.memo caches a component's output.

Serve Smaller Images

  • Use modern formats such as AVIF and WebP, and SVG for icons and logos
  • Add loading="lazy" to images below the fold so they load as the user scrolls
  • Serve different sizes for different screens with srcset and sizes
  • Compress images before upload, or use an image CDN that does it for you

Frequently Asked Questions (FAQs)

Why should I use React Fragments instead of wrapper <div> elements?

React Fragments help reduce unnecessary DOM nodes, making your page load faster and your component structure cleaner.

How do default props improve my React app?

Default props ensure your components function even if no values are passed, preventing undefined errors and improving user experience.

What is the impact of using useCallback on performance?

useCallback prevents unnecessary re-renders by memoising functions, which is particularly useful in apps with many child components.

Are inline styles bad for performance?

Yes, because inline styles reduce page loading efficiency and caching capabilities. Using external styles or CSS-in-JS libraries like styled-components is better.

Should I always use export default for React components?

While not mandatory, using export default for primary components simplifies imports and maintains consistency across your project.

Why is using unique keys in lists important for performance?

Unique keys help React identify which items have changed, improving rendering efficiency and preventing layout issues.

Watch these React tips on YouTube(opens in a new tab)

A short video walkthrough of the same tips, if you would rather watch than read.

Share this
Build work

Need this built properly?

I build the web and mobile products these notes come out of, in React, React Native and Node. A first conversation costs nothing and often ends with a smaller scope than you expected.

Not ready to book a call? Get a free website health check