Conditional Rendering

Course: React JS & Tailwind CSS - Full Course

Introduction

So far, every component we’ve built always shows the same thing. But in real applications, what you see on the screen often depends on some condition.

For example, if a user is not logged in, show a "Log In" button or only rendering tasks that are in progress. This idea of showing different things depending on a condition is called conditional rendering.

Conditionally Rendering UI

To demonstrate conditionally rendering UI, we'll use the task tracker we've been using as an example. This time we'll add an additional key to our tasks to indicate whether a task is completed or not:

 const tasks = [
    { id: 1, name: "Buy groceries", isComplete: true },
    { id: 2, name: "Clean room", isComplete: false },
    { id: 3, name: "Do homework", isComplete: true }
  ]

Given the tasks above, how would you go about rendering only the tasks that are complete? Try to give it a shot before looking ahead.

Filter Then Map

Remember, we can use curly braces to work on JavaScript it react. So what we can do is take our tasks, filter them using the .filter() method and then map over them like this:

<ul>
  {tasks
    .filter(task => task.isComplete)
    .map(task => (
      <li key={task.id}>{task.name}</li>
    ))}
</ul>

Remember, in JavaScript, the filter function will take the tasks array and return an array of tasks where isComplete is true.

Alternatively, to keep things a little more clear, I prefer to hold the filtered tasks in another variable, and then map over the filtered tasks, like this:

const completedTasks = tasks.filter((task) => task.isComplete)

  return (
    <div>
      <h2>Completed Tasks</h2>
      <ul>
        {completedTasks.map((task) => (
          <li key={task.id}>{task.name}</li>
        ))}
      </ul>
    </div>
  )

Both methods work, but this makes the code a little easier to read.

Ternary Operator (? :)

The ternary operator is a shorthand for if...else. It looks like this:

condition ? expressionIfTrue : expressionIfFalse

Basically, if the condition evaluates to true, then we render what's left of the semicolon, if false then what's on the right.

Let’s bring it back to our tasks example. Suppose you want to show only the completed tasks:

 <ul>
        {tasks.map((task) =>
          task.isComplete ? <li key={task.id}>{task.name}</li> : null
        )}
  </ul>

Essentially, what's happening is if isComplete is true, the task will get rendered, and if is false, nothings is rendered.

Alternatively, if you wanted to render a task that started with a particular letter or word, you can do so as well:

 {tasks.map((task) =>
          task.name.startsWith("Buy") ? <li key={task.id}>{task.name}</li> : null
        )}

In the above scenario, if the task starts with "Buy", then it will render the task.

Logical AND (&&)

Sometimes you only want to show something if a condition is true, and show nothing otherwise. For that, you can use the && operator. In React, it checks if left side is true, if it is, React will render the right side.

Using the task list from above, we can achieve the same goal with the following code:

 <ul>
        {tasks.map((task) => (
          task.isComplete && <li key={task.id}>{task.name}</li>
        ))}
 </ul>

However, it is worth noting, the above method works because isComplete is a boolean value. If we change the isComplete value to a string, it'll evaluate as true and the task will get rendered:

 const tasks = [
    { id: 1, name: "Buy groceries", isComplete: true },
    { id: 2, name: "Clean room", isComplete: "something" },
    { id: 3, name: "Do homework", isComplete: true }
  ]

If we use the above tasks, all of them will get rendered. So when working with the logical AND, the right side will render if the left is truthy.

And there you have it! The basics of conditional rendering. Conditional rendering can get a bit more complicated when we start nesting ternaries and && operators, but this is a good starting point!