Home > References > Web Development > Reactjs references

if-else statement inside jsx

Last updated : June 19, 2022

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
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Comments are disabled

No Comments