· tips  · 4 min read

Conditional Rendering Magic

Learn how to render UI conditionally in a single line using ternary operators. Real-world examples in React, Vue, and plain JavaScript-with tips to keep one-liners readable and maintainable.

Learn how to render UI conditionally in a single line using ternary operators. Real-world examples in React, Vue, and plain JavaScript-with tips to keep one-liners readable and maintainable.

What you’ll get from this post

By the end of this article you’ll be able to: write concise single-line conditional renders, choose between ternary and short-circuit patterns, and apply these techniques to real UI scenarios (login states, loaders, role-based badges, error messages). Short. Practical. Immediately usable.

Quick refresher: the ternary operator

The ternary operator in JavaScript has the form:

condition ? expressionIfTrue : expressionIfFalse;

It’s an expression (it returns a value), so it’s perfect for inline rendering. Use it when you want a single concise result based on a boolean condition.

Reference: MDN - Conditional (ternary) operator.

Why single-line conditional rendering?

Because sometimes clarity and brevity win. A single-line conditional keeps small UI choices readable at the call site: a class toggle, a tiny label, or swapping between two compact components. But single-line doesn’t mean single-minded-readability should guide you.

React: common single-line patterns (JSX)

React is where the one-liner ternary shines. It’s an expression that returns JSX directly.

  • Simple presence: show a login link or user avatar.
// Single-line in a render/return block
{
  user ? <Avatar user={user} /> : <a href="/login">Log in</a>;
}
  • Loading spinner vs content:
{
  isLoading ? <Spinner /> : <ArticleList items={items} />;
}
  • Role badge (single line, readable):
<span className={isAdmin ? 'badge badge-admin' : 'badge'}>
  {isAdmin ? 'Admin' : 'Member'}
</span>
  • Input validation message inline:
{
  /* show message if error exists, else show hint */
}
<p className="hint">{error ? <strong>{error}</strong> : 'Enter your email'}</p>;

React docs for conditional rendering: React - Conditional Rendering.

TypeScript + JSX

Type annotations rarely change the single-line nature, but they help catch mistakes early.

type Props = { user?: User | null };
const Greeting: React.FC<Props> = ({ user }) => (
  <div>{user ? `Hi, ${user.name}` : 'Welcome, guest'}</div>
);

Vue templates: in-template ternary

Vue’s template expressions support ternary operators as well. Keep them short though.

<template>
  <div>
    <p>{{ isLoggedIn ? `Hello, ${user.name}` : 'Please sign in' }}</p>
    <button :class="isActive ? 'btn-primary' : 'btn-secondary'">
      {{ isActive ? 'Active' : 'Activate' }}
    </button>
  </div>
</template>

Vue docs: Vue - Conditional Rendering.

Plain JavaScript / template literals

When injecting small fragments into innerHTML or templates, ternaries keep markup concise.

container.innerHTML = `
  <div>
    ${isMember ? `<span class="member">Member</span>` : `<a href="/join">Join</a>`}
  </div>
`;

Short-circuit (&&) vs ternary

Short-circuiting with && is common and shorter when you only need to render something on true and render nothing otherwise.

{
  isOpen && <Dropdown />;
}

But short-circuiting can’t express the “else” branch. When you need both branches, use ternary:

{
  isOpen ? <Dropdown /> : <Button onClick={open}>Open</Button>;
}

See MDN for short-circuit behavior and truthy/falsy nuances: MDN - Logical AND (&&).

Real-world scenarios and one-line examples

Below are typical UI needs and one-line solutions you can drop into your render function.

  1. Authentication-controlled CTA
{
  user ? (
    <button onClick={logout}>Sign out</button>
  ) : (
    <a href="/signup">Create account</a>
  );
}
  1. Feature flags (show new UI if enabled)
{
  flags.newCheckout ? <NewCheckout /> : <LegacyCheckout />;
}
  1. Inline form feedback (green check / red error)
<span className={`status ${valid ? 'ok' : 'error'}`}>
  {valid ? 'Looks good' : 'Fix this field'}
</span>
  1. Small icon toggles (e.g., favorites)
<button aria-pressed={favorited}>{favorited ? '★' : '☆'}</button>
  1. Empty state vs data table
{
  items.length ? (
    <Table items={items} />
  ) : (
    <EmptyState message="No items yet" />
  );
}

Advanced: keep single-line but improve readability

When ternaries grow long, you can preserve a single-line result at the call site by moving logic into helpers or using mapping objects.

  • Helper function (keeps render line short):
const renderButton = () => (isSubscribed ? <Unsubscribe /> : <Subscribe />);

// in JSX
{
  renderButton();
}
  • Object mapping (great for multi-case single-line lookups):
const statusMap = {
  loading: <Spinner />,
  success: <SuccessMessage />,
  error: <ErrorMessage />,
};

// single line lookup with fallback
{
  statusMap[status] || null;
}
  • Inline IIFE if you must compute then return a single-line JSX (rarely necessary):
{
  (() => (isAuth ? <Dashboard /> : <PublicLanding />))();
}

All of the above allow the JSX expression to remain a one-liner without sacrificing maintainability.

Pitfalls and how to avoid them

  • Nested ternaries become unreadable fast. Avoid more than one nested ternary. Break logic into helpers.
  • Don’t perform side-effects inside expressions. Expressions should be pure and quick.
  • Be careful with falsy values: 0, ” or null can cause unexpected short-circuiting. Check specifically when needed.
  • Long expressions hurt accessibility. If a conditional affects ARIA attributes, ensure both branches are accessible.

Practical style rules (a short checklist)

  • Prefer ternary when you need both branches. Use && only for the “render-or-nothing” case.
  • Keep each ternary simple. If it feels long, extract into a function.
  • Use object maps for multi-case rendering to avoid nested ternaries.
  • Comment complex one-liners sparingly-prefer small named helpers instead.

Summary: micro-magic with a safety net

Ternary operators let you express UI choices in a single line-concise and direct. Use them for small, self-contained decisions: toggles, badges, tiny content swaps. But keep readability your north star. When logic grows, extract or map. A short one-liner is satisfying. Clarity is the real magic.

Further reading:

Back to Blog

Related Posts

View All Posts »
The Magic of Default Parameters: Avoiding Undefined Errors

The Magic of Default Parameters: Avoiding Undefined Errors

Default parameters turn brittle functions into resilient ones. Learn how to use defaults in JavaScript, Python and TypeScript to avoid 'undefined' bugs, sidestep common pitfalls like mutable defaults and falsy-value traps, and make your code clearer and safer.

Destructuring Function Arguments: A Cleaner Approach

Destructuring Function Arguments: A Cleaner Approach

Learn how to simplify and clarify JavaScript function signatures with parameter destructuring. See side-by-side examples, real-world patterns, pitfalls, and TypeScript usage to write more readable, maintainable code.