React Ternary Operator
Table of Contents + −
In the last lesson on React Conditional Rendering you learned to choose what to show with an if. This lesson shows how to make that choice right inside the JSX, where an if cannot go.
🤔 Why do we need the ternary operator?
An if statement is great, but it has one limit inside JSX. Here is the gap.
- An
ifstatement is a statement. It does an action, but it does not give back a value you can drop into JSX. - JSX curly braces only accept expressions. An expression is a small piece of code that produces a value, like
2 + 2oruser.name. - So you cannot write
{ if (loggedIn) ... }inside JSX. React will throw an error. - You need something that does the same “pick A or B” job but produces a value. That something is the ternary operator.
So the short version is this. if chooses outside the JSX. The ternary chooses inside the JSX, right where you need the value.
❓ What is the ternary operator?
The ternary operator is a tiny one-line way to choose between two values based on a condition.
- It is written as
condition ? whenTrue : whenFalse. - React reads the condition first. If it is true, you get the value after the
?. If it is false, you get the value after the:. - It is called ternary because it takes three parts: the condition, the true value, and the false value.
- The whole thing produces one value. That is exactly why it fits inside JSX curly braces.
A simple way to picture it is a light switch with two labels. The switch position is the condition. One label shows when it is on, the other shows when it is off. You always get one label, never both.
It is just a compact if/else
condition ? a : b does the same job as an if/else, but it gives back a value instead of running statements. That is why you can use it inside JSX where an if would not fit.
🧩 The syntax
Here is the shape of a ternary on its own, before we put it inside JSX. This reads “if isLoggedIn is true, use Welcome, otherwise use Please log in”.
const message = isLoggedIn ? "Welcome" : "Please log in";So the value of message depends on isLoggedIn. See the three parts at work here:
- The condition comes before the
?. - The true value sits between
?and:. - The false value comes after the
:. - You get exactly one of the two, never both.
💡 Choosing between two pieces of UI
This is where the ternary really shines in React. You can pick which component to show, right inside the return.
- We keep an
isLoggedInvalue in state withuseState. - Inside the JSX, a ternary chooses between two components based on that value.
- When
isLoggedInis true, React renders<Dashboard />. When it is false, React renders<Login />. - A button flips the state, so the screen swaps between the two.
Here is the full component. Read the return first, then see how the button flips the state.
import { useState } from "react";
function App() { const [isLoggedIn, setIsLoggedIn] = useState(false);
return ( <div> {isLoggedIn ? <Dashboard /> : <Login />} <button onClick={() => setIsLoggedIn(!isLoggedIn)}> Toggle login </button> </div> );}So one line picks the whole screen. When isLoggedIn is false you see <Login />. Click the button, the state flips to true, React re-renders, and now you see <Dashboard />. The ternary swaps the UI for you.
🔤 Using it for text and values too
The ternary is not only for components. It works for any value, so it is perfect for small things like a button label or a class name.
- A button that flips between “Log out” and “Log in” is a classic use.
- The condition picks the right text, and React shows whichever one matches the current state.
- You can use this for a heading, a count message, an image source, anything that has two versions.
Here is a single button whose label flips based on isLoggedIn. Notice the ternary sits right inside the button text.
function LoginButton() { const [isLoggedIn, setIsLoggedIn] = useState(false);
return ( <button onClick={() => setIsLoggedIn(!isLoggedIn)}> {isLoggedIn ? "Log out" : "Log in"} </button> );}So the same button reads “Log in” when you are logged out, and “Log out” when you are logged in. One ternary, one button, two labels.
Great for one of two values
Reach for a ternary whenever you need one of exactly two things: this text or that text, this component or that component, this class or that class. It keeps the choice right next to where you use it.
🚫 Nesting ternaries is a smell
A ternary is clean when it picks between two things. The trouble starts when you stack ternaries inside ternaries to handle three or more cases.
- A nested ternary chooses A, otherwise checks another condition, otherwise picks B or C.
- It works, but it gets very hard to read. Your eyes have to track every
?and:to figure out what shows when. - When you feel the urge to nest, that is a sign the logic belongs outside the JSX, not crammed into one line.
- The fix is to pull the choice into a variable or a small helper above the return, then use that variable in the JSX.
This shows a deeply nested ternary versus pulling the logic out into a clean variable.
// ❌ Hard to read: ternaries nested inside ternariesreturn ( <div> {status === "loading" ? <Spinner /> : status === "error" ? <ErrorMessage /> : status === "empty" ? <EmptyState /> : <DataList />} </div>);
// ✅ Pull the logic out, keep the JSX cleanlet content;if (status === "loading") content = <Spinner />;else if (status === "error") content = <ErrorMessage />;else if (status === "empty") content = <EmptyState />;else content = <DataList />;
return <div>{content}</div>;So here is the simple rule to follow:
- Two outcomes? A single ternary inside the JSX is perfect.
- Three or more? Move the choice out into a variable with
if/elseabove the return. - That way the JSX stays readable, and anyone reading it can follow the logic at a glance.
Keep ternaries flat
One ternary in your JSX is clean. A ternary inside another ternary is a warning sign. For three or more cases, pull the logic into a variable above the return with if/else instead of nesting.
🧩 What You’ve Learned
- ✅ The ternary operator is written
condition ? whenTrue : whenFalseand produces a single value - ✅ It fits inside JSX curly braces because it is an expression, while an
ifstatement is not - ✅ You can use it to choose between two components, like
{isLoggedIn ? <Dashboard /> : <Login />} - ✅ It also works for text and other values, like a button label that flips between two words
- ✅ A single flat ternary is clean and readable inside JSX
- ✅ Nesting ternaries is a smell — for three or more cases, pull the logic into a variable with
if/elseabove the return
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
Why can you use a ternary inside JSX curly braces but not an if statement?
Why: JSX curly braces only accept expressions, which produce a value. A ternary produces one of two values, so it fits. An if statement runs an action but does not give back a value, so it cannot go inside the braces.
- 2
What does condition ? a : b give you when the condition is false?
Why: When the condition is true you get the value after the ?, and when it is false you get the value after the :. So a false condition gives you b.
- 3
How would you show <Dashboard /> when logged in and <Login /> otherwise, inline in JSX?
Why: The ternary {isLoggedIn ? <Dashboard /> : <Login />} picks one of the two components based on the condition, right inside the JSX. You cannot put a raw if statement inside the braces.
- 4
What should you do when you need to choose between three or more pieces of UI?
Why: Nested ternaries get very hard to read. For three or more cases, move the choice into a variable with if/else above the return and use that variable in the JSX. The JSX stays clean and easy to follow.
🚀 What’s Next?
Now you can switch between two pieces of UI inline with a ternary. But sometimes you only want to show something or nothing at all, with no second option. There is an even shorter way to do that.