← All posts

Programming 2 min read

Understanding JSX: Why if Statements Cause Syntax Errors

Why JSX curly braces only accept JavaScript expressions and how transpilation breaks down under the hood.

Understanding JSX: Why if Statements Cause Syntax Errors

The Problem: if Statements in JSX

I remember the first time I used JSX. I was trying to render information based on a condition, so I wrote the following:

JavaScript


{
  if (isLoggedIn) {
    return <p>Welcome</p>
  } else {
    return <Login />
  }
}

This wouldn't compile, and I was scratching my head as to why it was wrong.

I looked online and found out that I had to use a ternary expression like this:

JavaScript

{ isLoggedIn ? <p>Welcome</p> : <Login /> }

That worked!

Why JSX Only Accepts Expressions

I came to find out that inside JSX curly brackets {} you can only place expressions. React needs something that evaluates to a value it can render.

Why?

Expressions vs. Statements

An expression outputs a value. It’s a piece of code that evaluates to a result.

Examples of expressions:

  • 5 + 5 (evaluates to 10)

  • isLoggedIn ? <p>Welcome</p> : <Login/> (evaluates to one of the JSX elements)

  • {formatDate(date)} a function that returns a value

  • {users.map(user => <UserCard key="{user.id}" user="{user}"/>)} (evaluates to an array of elements)

A statement, on the other hand, performs an action but doesn't evaluate to a value.

Examples of statements:

  • if (...) { ... }

  • for (...) { ... }

Because JavaScript if statements don't evaluate to a value, placing them directly inside JSX curly braces causes a syntax error.

Under the Hood: Function Arguments and React.createElement

When JSX transpiles into plain JavaScript via Babel, curly braces are transformed directly into function arguments for calls like React.createElement(type, props, children). Since you cannot pass an if statement as an argument to a JavaScript function call, the children argument must be an expression that has already been evaluated rather than control-flow code that needs to execute.

For example, if you create a function like this:  

JavaScript

function sayHello(name) {
  console.log("Hello " + name);
}

If you were to call this function by writing:

JavaScript

sayHello(if (isMan) { "luke" } else { "marie" }) // ❌ Syntax error!

This wouldn't compile because you can't pass an if statement as an argument.

However, if you use an expression, it works as expected:

JavaScript

sayHello(isMan ? "luke" : "marie") // ✅ Works!