≡ Menu

react coniditional rendering

React’s power lies in its ability to manage a dynamic UI based on the current application state. The mechanism for showing different elements, components, or entire views based on specific conditions is called conditional rendering.

Mastering these techniques is fundamental to building clean, efficient, and maintainable React applications. Here are the most common and effective ways to conditionally render in React.

1. The if/else Statement (Outside JSX)

The most straightforward way to conditionally render is using standard JavaScript if/else or switch statements before the return in a functional component, or within the render() method of a class component.

This method is great for handling conditions that determine the entire output of the component.

function Greeting({ isLoggedIn }) {
  if (isLoggedIn) {
    return <h1>Welcome back!</h1>;
  }
  return <h1>Please sign up.</h1>;
}

2. The Ternary Operator (? :) (Inline JSX)

 

The ternary operator is arguably the most common and concise way to conditionally render a small portion of output inside your JSX. It’s perfect for when you need to switch between two different elements based on a condition.

$$condition ? \text{expression\_if\_true} : \text{expression\_if\_false}$$

 

function UserStatus({ user }) {
  return (
    <div>
      {user.isVerified ? (
        <p> Account verified.</p>
      ) : (
        <p> Please verify your account.</p>
      )}
    </div>
  );
}

3. Logical AND Operator (&&) (Short-Circuiting)

 

When you only want to render something if a condition is true, and render nothing if it’s false, the Logical AND (&&) operator is your best tool. This technique utilizes JavaScript’s “short-circuiting” behavior.

In JavaScript, if the expression on the left of && is true, the expression on the right is evaluated and returned. If the left side is false (or a falsy value like 0, "", null, or undefined), the right side is skipped, and the falsy value is returned, which React treats as “do not render.”

function UnreadMessages({ count }) {
  return (
    <div>
      <h1>Hello!</h1>
      {/* Renders the alert ONLY if count > 0 */}
      {count > 0 && <h2>You have {count} unread messages.</h2>}
    </div>
  );
}

⚠️ Note on Falsy Values: Be careful with values like 0. If count above was 0, the && expression would evaluate to 0, and React would actually render the number 0 on the screen. To prevent this, ensure your left-hand condition strictly evaluates to a boolean (e.g., $count > 0$ instead of just $count$).


4. Element Variables (Pre-defining the Element)

 

For more complex conditions that involve several paths, using an element variable can keep your JSX clean. You define the element to be rendered in a standard JavaScript variable outside the return statement, typically using if/else or switch, and then place that variable inside your JSX.

function AdminPanel({ role }) {
  let panelComponent;

  if (role === 'admin') {
    panelComponent = <FullAccessPanel />;
  } else if (role === 'editor') {
    panelComponent = <EditorAccessPanel />;
  } else {
    panelComponent = <p>Access denied.</p>;
  }

  return (
    <div className="admin-container">
      {/* Simply render the pre-defined variable */}
      {panelComponent}
    </div>
  );
}

5. Returning null (Hiding a Component)

If you want to prevent a component from rendering anything at all, you can have it return null. This is often used when a component needs to perform some internal logic but should not produce any output under certain circumstances.

function WarningSign({ shouldDisplay }) {
  if (!shouldDisplay) {
    // Component renders nothing
    return null;
  }

  return (
    <div className="warning">
      <p>🚨 Warning: Danger ahead!</p>
    </div>
  );
}

Summary: Choosing the Right Tool

 

Scenario Recommended Technique Why?
Two possibilities (A or B) Ternary Operator (? :) Most concise for inline rendering of one of two things.
Render or not render (A or nothing) Logical AND (&&) Excellent for concise, single-condition checks inside JSX.
Complex logic (3+ possibilities) if/else with Element Variables Keeps complex branching logic outside the JSX for better readability.
Entire component output depends on state if/else (outside return) Simple, clear control flow for the whole component function.

By strategically applying these techniques, you can ensure your React components only render what they need, leading to a dynamic, responsive, and easy-to-read user interface!

Useful links below:

Let me & my team build you a money making website/blog for your business https://bit.ly/tnrwebsite_service

Get Bluehost hosting for as little as $1.99/month (save 75%)…https://bit.ly/3C1fZd2

Join my Patreon for one-on-one coaching and help with your coding…https://www.patreon.com/c/TyronneRatcliff

Buy me a coffee ☕️https://buymeacoffee.com/tyronneratcliff

{ 0 comments }

Have you ever noticed your application stuttering when you switch categories or type in a search box?

This is a classic symptom of unnecessary re-renders in React.

For dynamic lists, especially product catalogs, a little bit of optimization goes a long way.

We’ll use a real-world code example to show you the powerful combination of two React tools—useMemo and React.memo—to keep your UI snappy and fast.


 

🛠️ The Problem: Wasted Work in React

 

In React, when a parent component re-renders (e.g., when a state updates), all its child components also re-render by default. This is usually fine, but when you have a list with hundreds of items, forcing every single item to update, even if its data hasn’t changed, is a massive waste of CPU cycles.

Our goal is to create optimization barriers to prevent this wasted work.


 

🚀 Solution 1: Memoize Expensive Calculations with useMemo

 

The most common source of lag in a product list is the data processing itself—things like filtering and sorting. We don’t want to re-filter our massive product list every time an unrelated piece of state changes (like a simple search input).

 

The Fix in OptimizedProductList

We use the useMemo hook to create a stable reference to our filtered product list.

// --- Main Optimized Component (Excerpt) ---
function OptimizedProductList() {
  const [activeCategory, setActiveCategory] = useState('Electronics');
  const [searchText, setSearchText] = useState(''); 
  
  // 💡 Optimization: useMemo filters the products ONLY when 'activeCategory' changes.
  const filteredProducts = useMemo(() => {
    console.log('*** FILTERING PRODUCTS (Only runs when category changes) ***');
    return ALL_PRODUCTS.filter(p => p.category === activeCategory);
  }, [activeCategory]); // Dependency Array: Only re-run when activeCategory changes.

  // ... rest of the component
}
  • How it Works: The filter function runs only when a dependency in the array (activeCategory) changes.
  • The Benefit: If the user starts typing in the searchText input, the OptimizedProductList component re-renders, but the filtering function inside useMemo is skipped entirely. This saves significant calculation time.

 

🎯 Solution 2: Prevent Child Re-renders with React.memo

 

While useMemo prevents re-calculating the list, we still have to prevent the individual product cards from re-rendering when the parent updates. This is where React.memo comes in.

 

The Fix on ProductCard

 

We wrap our ProductCard functional component with React.memo.

 

// --- ProductCard Component ---
// 💡 Optimization: React.memo prevents re-render unless its 'product' prop changes.
const ProductCard = React.memo(({ product }) => {
  // Console log to observe re-renders
  console.log(`Rendering Product: ${product.name}`); 
  // ... JSX for the card
});
  • How it Works: React.memo is a Higher-Order Component (HOC) that automatically compares the component’s props between renders.
  • The Benefit: When the user types in the searchText field, the parent component re-renders, but the filteredProducts array reference passed to the list is the same (thanks to useMemo). Since the props for each ProductCard haven’t changed, React.memo tells React to skip rendering that component, avoiding hundreds of needless updates.

 

📈 The Final, Optimized Code in Action

 

By combining these two techniques, we create an optimized component that only performs work when the data that affects the list actually changes.

// Complete Optimized Code

function OptimizedProductList() {
  const [activeCategory, setActiveCategory] = useState('Electronics');
  const [searchText, setSearchText] = useState(''); 
  
  // 1. Data Filtering (useMemo)
  const filteredProducts = useMemo(() => {
    console.log('*** FILTERING PRODUCTS (Only runs when category changes) ***');
    return ALL_PRODUCTS.filter(p => p.category === activeCategory);
  }, [activeCategory]);

  // ... rest of the component
  return (
    <div>
      {/* ... Filter/Search UI */}
      <input
        value={searchText}
        onChange={(e) => setSearchText(e.target.value)}
        placeholder="Type to cause a parent re-render..."
      />
      <p>Parent component re-rendered ({searchText})</p>
      
      <hr />
      
      <div className="product-list">
        {/* 2. List Rendering (ProductCard is wrapped in React.memo) */}
        {filteredProducts.map(product => (
          <ProductCard key={product.id} product={product} />
        ))}
      </div>
    </div>
  );
}

Try It: With this setup, typing in the search bar only causes the parent to update the searchText counter. It does not trigger the *** FILTERING PRODUCTS *** console log, and more importantly, it does not trigger the Rendering Product: log for the child components!

Your product list is now fast, efficient, and ready for your next e-commerce feature!

Useful links below:

Let me & my team build you a money making website/blog for your business https://bit.ly/tnrwebsite_service

Get Bluehost hosting for as little as $1.99/month (save 75%)…https://bit.ly/3C1fZd2

Join my Patreon for one-on-one coaching and help with your coding…https://www.patreon.com/c/TyronneRatcliff

Buy me a coffee ☕️https://buymeacoffee.com/tyronneratcliff

{ 0 comments }