Conditional Rendering

Composi allows you to conditionally render the elements that a component produces.

You can use JavaScript operators like if and else, or the ternary operator when making decisions about what markup a component should create.

As an example of conditional rendering, lets use a situation where depending on whether the user is logged in or not, we render two different sub-components. Here's the two possible components:

function UserGreeting(props) {
  return <h1>Welcome back!</h1>
}

function GuestGreeting(props) {
  return <h1>Please sign in.</h1>
}

Now lets create a component that returns these two sub-components and based on the loggedon condition, returns one or the other. Try opening the Codepen and changing the value of isLoggedIn to false.

See the Pen Composi Tuts - conditional-rendering-1 by Robert Biggs (@rbiggs) on CodePen.

Conditional Element Variables

You can use a variable to conditionally store an element and then return that in the render function. In the next example we are going to combine the Greeting element from above with conditional rendering of buttons for a login. When the user clicks the button, the logged in status will change visibly on the page. Notice how we store the button in a variable and out put it with {button} in the component's render function, keeping it very clean:

See the Pen Composi Tuts - conditional-rendering-2 by Robert Biggs (@rbiggs) on CodePen.

Using the Logical && Operator

You can also use the JavaScript logical && operator for conditional situations. In the above example we can simplify the handleEvent method by using the && operator as a condition check:

// Original with if statement:
handleEvent(e) {    
  if (e.target.class === 'login') {
    this.handleLoginClick(e)
  } else if (e.target.class === 'logout') {
    this.handleLogoutClick(e)
  }
}

// New version using &&
  handleEvent(e) {    
  e.target.class === 'login' && this.handleLoginClick(e)
  e.target.class === 'logout'&& this.handleLogoutClick(e)
}

When you see an expression like this, read it like this: When e.target.class equals "login", execute this.handleLoginClick(e)". Basically, the first part is a check, if it is true then the && will execute whatever follows.

We can also use the && operator to conditionally render an element. If the first statement is true, then return the element to render. In the next example, the element will render only if the number of messages is greater than 0:

See the Pen Composi Tuts - conditional-rendering-3 by Robert Biggs (@rbiggs) on CodePen.

Inline Ternary Operator

Another way to render things conditionally is to use the JavaScript ternary operator: condition ? true : false. The ternary operator is great for reducing conditional if/else statements to a single line. However, creating nested ternary statements results in difficult to read code, so avoid doing that.

You can use the ternary operator for simple decisions about what to print out based on a condition:

render() {
  const isLoggedIn = this.state.isLoggedIn
  return (
    <div>
      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
    </div>
  )
}

As you can see, using the ternary operator makes the test clean and easy to reason about.

In our previous example we had a render function like this:

render() {
  const isLoggedIn = this.state.isLoggedIn

  if (isLoggedIn) {
    button = <LogoutButton />
  } else {
    button = <LoginButton />
  }

  return (
    <div>
      <Greeting isLoggedIn={isLoggedIn} />
      {button}
    </div>
  )
}

Using the ternary operator, we can simplify the logic to this:

render() {
  const isLoggedIn = this.state.isLoggedIn;

  return (
    <div>
      { isLoggedIn ? <LogoutButton /> : <LoginButton /> }
    </div>
  );
}

Prevent an Component from Rendering

Sometimes you want to not render a component from rendering. The best way to do that is to test for a condition and have the render function return null. Notice how we do that with the WarningBanner component below:

See the Pen Composi Tuts - conditional-rendering-5 by Robert Biggs (@rbiggs) on CodePen.

Because WarningBanner is a child component to Page, when WarningBanner returns null, that only affects its output. It will not affect the output of the button nor the lifecycle methods and events.