Why can I use a ternary operator inside a JSX expression but not an if statement?

Question

Why can I use a ternary operator inside a JSX expression but not an if statement?

Answer

We can use a ternary operator, also known as a conditional operator, inside a JSX expression because it will always evaluate to a value, where as an if/else/else if statement is not only not an expression (it’s a statement and will execute a statement based on the value of an expression), but will also not evaluate to a value.

In other words, we cannot use a statement where a value (or expression) is expected and for this reason, we cannot use statements, including the conditional if/else/else if statements, inside a JSX expression.

10 Likes

If we really want to use an if statement inside a JSX expression, I think there is a way that we rewrite it as a function which always returns a value, and call it immediately. I tried the following code and this worked too:

const img = <img src={(
  () => {
    if (coinToss() === 'heads') {
      return pics.kitty;
    } else {
      return pics.doggy;
    };
  })()} />;
18 Likes

I just want to confirm whether i am getting your code the right way !!
As far as I can assess you have made an arrow head function and used () to make it a function call !

2 Likes

Yes, I made an arrow function and called it with ().

3 Likes

Why do we need to wrap the function coinToss with square brackets?

const img = <img src={pics[coinToss() === ‘heads’ ? ‘kitty’ : ‘doggy’]} />;

1 Like

It is not coinToss() which is wrapped in square brackets but the whole ternary/conditional expression which is

coinToss() === ‘heads’ ? ‘kitty’ : ‘doggy’

The above expression will finally evaluate to either ‘kitty’ or ‘doggy’ . On substituting the expression with values it will become

pics[‘kitty’]

or

pics[‘doggy’]

Now pics is an already defined object. The above expression will be getting values for respective keys.

8 Likes

Why do we use quotation marks in:
const img = <img src={pics[coinToss()===‘heads’ ? ‘kitty’ : ‘doggy’]} />;

for kitty and doggy since they are js variables?
wouldn’t img = be the result?

there is two way to access a value from an object

  1. dot notation
    eg:- pics.kitty
  2. square baracketing
    eg:- pics[‘kitty’}
    mostly second one is used for keys that having spaces so quotation mark is necessary
11 Likes

One way I find helpful to reason about is this:

An expression is something that could be on the right side of an assignment statement.

var myVar = /* any valid Javascript Expression goes here */;

So looking at

let myVar;
if(someCondition) {
  myVar = 10;
} else {
  myVar = 20;
}

versus

const myVar = someCondition ? 10 : 20;

There’s no way to wrap the whole if statement inside a single expression that could be used on the right side of an assignment.

{if(someCondition) { /* what would even go here? */ }}

However the ternary above is an expression

{someCondition ? 10 : 20 }
2 Likes

you saved me so many headaches, thank you

1 Like

Nice trick! It got my attention.

1 Like

I read the document and it says:

if-else statements don’t work inside JSX. This is because JSX is just syntactic sugar for function calls and object construction.

This means that if statements don’t fit in. Take this example:

// This JSX:
<div id={if (condition) { 'msg' }}>Hello World!</div>

// Is transformed to this JS:
React.createElement("div", {id: if (condition) { 'msg' }}, "Hello World!");

That’s not valid JS. You probably want to make use of a ternary expression:

ReactDOM.render(<div id={condition ? 'msg' : null}>Hello World!</div>, mountNode)

My problem with that is that it doesn’t show us how the ternary operator is transformed to JS. Does anyone know how that is?

Hi,

I can try to answer your question.
The ternary operator is already basic JS and it does not need any transformation.
So the JSX element <div id={condition ? 'msg': null }>Hello World!</div> would be translated to:

React.createElement("div", {id: condition ? 'msg': null }, "Hello World!");