Loading

Quipoin Menu

Learn • Practice • Grow

react / if-else in JSX
tutorial

if-else in JSX

You might wonder: can I use an `if` statement directly inside JSX? The short answer is no – JSX doesn't support `if` statements. But there are several patterns to achieve the same result while keeping your code clean and readable.

Why Can't We Use if-else Inside JSX?

JSX is just syntactic sugar for `React.createElement()` calls. It's designed to be declarative, not imperative. `if-else` is an imperative statement, not an expression, so it can't be used directly inside JSX.

JSX only accepts expressions (things that evaluate to a value), not statements (instructions). That's why we use ternary operators instead of if-else inside JSX.

Pattern 1: Move if-else Outside JSX

The simplest solution is to move the conditional logic outside the JSX:
function UserGreeting({ user }) {
  let greeting;

  if (user) {
    if (user.premium) {
      greeting = <h1>Welcome back, Premium Member {user.name}!</h1>;
    } else {
      greeting = <h1>Welcome back, {user.name}!</h1>;
    }
  } else {
    greeting = <button>Sign In</button>;
  }

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

This is clean, readable, and works perfectly for complex logic.

Pattern 2: Immediately Invoked Function Expression (IIFE)

You can use an IIFE inside JSX, though this is less common:
function Message({ type }) {
  return (
    <div>
      {(() => {
        if (type === 'success') {
          return <p style={{ color: 'green' }}>Operation successful!</p>;
        } else if (type === 'error') {
          return <p style={{ color: 'red' }}>Something went wrong!</p>;
        } else {
          return null;
        }
      })()}
    </div>
  );
}

While this works, it's not very readable and should be used sparingly.

Pattern 3: Helper Function

Create a separate function that returns JSX based on conditions:
function getNotificationContent(type) {
  if (type === 'success') {
    return <SuccessIcon />;
  } else if (type === 'warning') {
    return <WarningIcon />;
  } else {
    return null;
  }
}

function Notification({ type, message }) {
  return (
    <div className="notification">
      {getNotificationContent(type)}
      <span>{message}</span>
    </div>
  );
}

This keeps your component clean and the logic well-organized.

Pattern 4: Element Variables

Store JSX in variables and then use them in your return:
function ShoppingCart({ items }) {
  let cartContent;

  if (items.length === 0) {
    cartContent = <p>Your cart is empty</p>;
  } else {
    cartContent = (
      <ul>
        {items.map(item => (
          <li key={item.id}>{item.name} - ${item.price}</li>
        ))}
      </ul>
    );
  }

  return (
    <div className="cart">
      <h2>Your Cart</h2>
      {cartContent}
    </div>
  );
}

This is very readable and great for when you have multiple conditions.

Pattern 5: Early Returns

For loading and error states, early returns are very effective:
function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  <!-- fetch logic here -->

  if (loading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }

  if (!user) {
    return <div>User not found</div>;
  }

  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
    </div>
  );
}

Two Minute Drill

  • You can't use `if-else` statements directly inside JSX because JSX only accepts expressions.
  • Move if-else outside: Do conditional logic before the return statement.
  • Element variables: Store JSX in variables based on conditions.
  • Helper functions: Create functions that return JSX based on parameters.
  • Early returns: Return early for loading, error, or empty states.
  • IIFEs: Use immediately invoked functions (not recommended for complex logic).
  • Choose the pattern that makes your code most readable and maintainable.

Need more clarification?

Drop us an email at career@quipoinfotech.com