[REACT](https://www.kirupa.com/react/index.htm) [BOOK](https://www.amazon.com/exec/obidos/ASIN/0134546318/kirupacom) # Conditional Rendering in React by [ kirupa](https://www.kirupa.com/me/index.htm) | filed under [Learning React](https://www.kirupa.com/react/index.htm) Almost no UI shows the same thing all the time. A menu is open or closed. A user is signed in or signed out. A list is loading, or it failed to load, or it loaded and there is nothing in it. If your app can't show different things at different times, it isn't much of an app. In React, there is no special syntax for any of this. There is no `v-if` or `*ngIf` to learn. Your components are JavaScript functions, and JSX is JavaScript, so you decide what to show using the same `if` statements, ternaries, and logical operators you already know. What takes a bit of practice is figuring out which one to use when, and a few traps are waiting for you along the way. In this tutorial, we'll go through each pattern, see when it reads best, and then look at something that surprises almost everyone: what happens to a component's state when you hide it. Onwards! ## The Basic Idea A component is a function, and what it returns is what ends up on the screen. If you want a component to show something different in different situations, you change what the function returns. That's the whole idea behind conditional rendering. Everything else in this tutorial is a different way to express it. To try the code in this tutorial, create a new Vite project (if you don't have one, follow along with [Easily Set Up Your React Dev Environment](https://www.kirupa.com/react/setting_up_react_environment.htm)) and replace the contents of `src/App.jsx` with whatever example we are looking at. For the examples that use state, we'll use the `useState` hook. You'll see it fully explained in [Dealing with State](https://www.kirupa.com/react/dealing_with_state.htm), so don't worry if some of it looks new. All you need to know for now is that state is a value a component remembers, and changing it makes the component run again with the new value. ## Using if and Early Returns The most direct way to render conditionally is an `if` statement at the top of your component. Here's a `Dashboard` that needs a user to be signed in: ```jsx function Dashboard({ user }) { if (!user) { return

Please sign in to see your dashboard.

; } return

Welcome back, {user.name}!

; } function App() { return (
); } export default App; ``` When you run this, you'll see two things: "Please sign in to see your dashboard." for the first `Dashboard`, and "Welcome back, Batman!" for the second. The `if` check at the top is called an **early return**. If the user is missing, we return right away, and the rest of the function never runs. This has a nice side effect. By the time we reach the main `return`, we know `user` exists, so we can use `user.name` without worrying about it blowing up. You'll use early returns a lot. They keep the main path of your component flat and easy to read, and the unusual cases get dealt with at the top and out of the way. An `if` statement can't live inside the JSX itself, though, because JSX curly braces accept expressions and not statements. When you want to decide something in the middle of your JSX, you need a different tool. ## The Ternary Operator The ternary (or conditional) operator is an expression: it takes a condition and gives you one of two values. That means it can go right inside your JSX: ```jsx function Greeting({ isLoggedIn }) { return (

My App

{isLoggedIn ?

Welcome back!

:

Please sign in.

}
); } ``` The part before the `?` is the condition. If it's true, you get what's between the `?` and the `:`. If it's false, you get what comes after the `:`. Render `` and you'll see the welcome message under the heading. Flip it to `false` and the sign-in message takes its place. A ternary is the right tool when there are exactly two outcomes and both are short. The moment either side gets long, or you start nesting a ternary inside another ternary, it becomes hard to read. At that point, reach for one of the options we'll see in a bit. ## Using && for Show-or-Nothing Sometimes you don't have an "else" at all. You either show something or you show nothing. A ternary works, but you'd have to write `: null` every time. The logical AND operator (`&&`) is a shorter way to say the same thing: ```jsx function Inbox({ unread }) { return (

Inbox

{unread > 0 && {unread} unread}
); } ``` Here is how this works. In JavaScript, `a && b` gives you `b` if `a` is truthy. Otherwise, it gives you `a`. When `unread` is 5, the condition is `true`, so we get the ``. When `unread` is 0, the condition is `false`, and React renders nothing for `false`. Render `` and you'll see "5 unread" next to the heading. Use `unread={0}` and you'll see only the heading. ### The 0 Gotcha Now let's make one tiny change. Instead of `unread > 0`, what if we just use `unread` as the condition, since a number is truthy when it isn't zero? ```jsx function Inbox({ unread }) { return (

Inbox

{unread && {unread} unread}
); } ``` This looks like it should work the same way, and with `unread={5}` it does. Now render it with `unread={0}`: ![A page with the heading Inbox followed by a stray number 0 below it](https://www.kirupa.com/react/images/conditional_zero_gotcha.png) There's a lonely `0` sitting under our heading! The cause is that `0 && anything` gives you `0`, since `0` is falsy and `&&` hands back the first falsy value it sees. React doesn't render `true`, `false`, `null`, or `undefined`, but it does render numbers, and `0` is a number. (An empty string renders as nothing, and `NaN` will show up as the text "NaN", so numbers are the main culprit.) The fix is to make sure the left side of the `&&` is a real boolean. Writing `unread > 0 && ...` does that, and so does `Boolean(unread) && ...`. Anytime the thing on the left is a number, like a length or a count, do this. We touched on this trap briefly in [Going from Data to UI](https://www.kirupa.com/react/from_data_to_ui_in_react.htm), and now you know the full story. ## Returning null Sometimes the thing that should disappear is the whole component. For that, your component can return `null`: ```jsx function Banner({ message }) { if (!message) { return null; } return
{message}
; } ``` When a component returns `null`, React renders nothing for it. It's still a perfectly fine component. It's just invisible for the moment. Our `Banner` is a good example: whoever uses it can render it all the time and pass in a `message` when there is something to say. With `message=""` you'll see nothing, and with `message="Hi"` you'll see the banner. This is the same early return we saw earlier, just with an empty result. Whether to let the component decide for itself (`return null`) or let the parent decide (`{message && }`) is a style choice. If the logic of "when should I be visible" belongs to the component, put it inside. If it's more about the situation the parent is in, keep it in the parent. ## Storing JSX in Variables Remember that JSX is just a value, and values can be stored in variables. This gives you a pattern that is handy when the condition is complicated, or when each outcome has a fair amount of JSX: ```jsx function AccountMenu({ user }) { let menu; if (user) { menu = (
Hi, {user.name}
); } else { menu = ; } return ; } ``` We use a regular `if` and `else` to decide what goes into `menu`, and then we drop `menu` into the returned JSX. The `