if-else statement inside jsx

Last updated : Jul 30, 2023 12:00 AM

You cannot use if-else statements inside JSX. If you want to check conditions inside JSX, use the ternary operator or put the conditional logic into a function and call that function from JSX.

React follows a declarative programming style. React compiles regular JSX expressions to regular JavaScript function calls. According to Official React docs, JSX just provides syntactic sugar. Let's take a look at the below JSX.

The message is a simple component. The Alert resides inside the Message component.

import { ReactNode } from "react";
import { Alert } from "react-bootstrap";
interface ButtonProps {
  props: StyleProps,
  children: ReactNode
}
interface StyleProps {
  variant: string,
}
const Message = ({props, children}: ButtonProps) =>{
  return(
     <div>
        <Alert variant={props.variant}>
        {children}
        </Alert>
     </div>
  )
}
export default Message

Listed below is the general usage of the Message component.

<Message props={{variant: "success"}}>
   Great Job!
</Message>

React translates this JSX to

React.createElement(Message, {
   props: {
      variant: "success"
   }
}, "Great Job!")

Then we have the Alert JSX in the Message component. React does another translation.

React.createElement(Alert, {
   variant: props.variant
}, children)

When you take the Message component as a whole, the React translation looks like

React.createElement(Message, {
   props: {
      variant: "success"
   }
},React.createElement(Alert, {
   variant: props.variant
}, children))

JSX expressions must have one parent element

As you can see, the result is a nested element. React starts from the top most parent JSX and nests all the JSX expressions as elements. The result is a deeply nested statement of React.createElements. That is the reason for the "JSX expressions must have one parent element" error when you don't wrap your JSX elements in a parent element. React doesn't know where to find the parent element to create the nested elements.

If-else in JSX elements

If you take a closer look at the resulted element, you will see there is no place for if-else statements. Therefore, we have two options when it comes to if-else inside JSX.

  1. Use ternary expressions,/li>
  2. Call a function from JSX

Using ternary expressions in JSX

Using ternary expressions in JSX works out great for simple if-else statements. When it comes to nested or complex if-else statements, deligating that logic to a function makes more sense.

{
   score === 100 ? 
      <Message props={{variant: "success"}}>Great Job!</Message> 
      : 
      <Message props={{variant: "info"}}>Good Job!</Message>
}

Call a function from JSX expression

Suitable for complex and lengthy if-else statements. The below code demonstrates how to use a function call to display a JSX element conditionally.

import { useState } from "react";
import Message from "./components/Message";

export const App = () => {
   const [score, setScore] = useState(0)

   const displayMessage = () => {
      if(score === 80){
         return <Message props={{variant: "info"}}>You have passed the test!</Message> 
      }
      else
      if(score === 90){
         return <Message props={{variant: "primary"}}>Good Job! You have passed the test!</Message> 
      }
      else
      if(score === 100){
         return <Message props={{variant: "success"}}>Great Job! You Nailed it!</Message> 
      }
      return <Message props={{variant: "warning"}}>Please enter your score</Message> 
   }

   return(
      <div style={{width:240}}>
         <div style={{padding:10}}>
         <label>Your Score: </label>
         <select name="select" onChange={(e) => setScore(+(e.target.value))}>
            <option value="0"></option>
            <option value="80">80</option>
            <option value="90">90</option>
            <option value="100">100</option>
         </select>
         </div>
         <div style={{padding:10}}>
            {displayMessage()}
         </div>
      </div>
   )
}
export default App;

Message Component

import { ReactNode } from "react";
import { Alert } from "react-bootstrap";
interface ButtonProps {
   props: StyleProps,
   children: ReactNode
}
interface StyleProps {
   variant: string,
}
const Message = ({props, children}: ButtonProps) =>{
   return(
      <div>
         <Alert variant={props.variant}>
         {children}
         </Alert>
      </div>
   )
}
export default Message
Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...