9

I have a question about the proposed JavaScript do expression construct. There are many examples that show how it can be used to return a value from a conditional statement that has both if and else. Also valid for if with else if and else.

What about a conditional that has just an if clause but no else if or else? Is this valid usage of the do expression?

My use case is for conditionally displaying content in a React component. I would like to write JSX code like so, but I am not sure if it is valid:

export default function myComponent(props) {
  return (
    <div>
      {do {
        if (true) {
          <p>If statement is true</p>
        }
      }}
      <p>I am always rendered</p>
    </div>
  );
}

I also asked the question in this gist.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
ecbrodie
  • 11,246
  • 21
  • 71
  • 120

5 Answers5

15

Not sure about do, also as mentioned by @Felix Kling

do expression is a stage 1 proposal, not part of ES2016 (ES7).


You can write it like this using ternary operator, and return null if condition fails:

export default function myComponent(props) {
    return (
        <div>
            {
                true?
                    <p>If statement is true</p>
                :null
            }
            <p>I am always rendered</p>
        </div>
    );
}

Or Use && Operator:

export default function myComponent(props) {
    return (
        <div>
            {
                true && <p>If statement is true</p>
            }
            <p>I am always rendered</p>
        </div>
    );
}

Check the DOC for more details about Conditional Rendering.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
6

Why not simply do this ? Using the Ternary operator

export default function myComponent(props) {
  return (
    <div>
      { true ? <p>If statement is true</p> : null }
      <p>I am always rendered</p>
    </div>
  );
}
Kush Patel
  • 110
  • 2
3

Here is what Babel does:

Input:

<p>
  {do {
    if (true) {
      <a/>
    }
  }}
</p>

Output:

React.createElement(
  "p",
  null,
  true ? React.createElement("a", null) : void 0
);

This makes sense to me. The return value in the implied else would be undefined.

000
  • 26,951
  • 10
  • 71
  • 101
  • In React, you want the return value for `else` (in this case) to be null, not undefined. Better to explicitly return null as in [this answer](https://stackoverflow.com/a/68169867/560114) – Matt Browne Mar 17 '22 at 11:32
  • Then open a ticket with Babel. I didn't write this code in my answer, I'm only showing what the compiler did. – 000 Jun 02 '22 at 15:58
  • I was talking about the original source code before Babel transpiles it. So `{do { if (true) { } null }}` – Matt Browne Jun 02 '22 at 17:38
  • ...or it looks like in the current version of the spec you would have an explicit `else` block (`else { null }`); not sure if Babel supports that yet – Matt Browne Jun 02 '22 at 17:41
2

Yes, it is a valid syntax to write a do expression without an else and it will return an undefined (void 0).

let a = do {
  if (false) true
}

// a === undefined

We can also return a value at the end without even using else like this:

let a = do {
  if (false) true
  null
}

// a === null

Especially for ReactJS, we have to return a null even using the do expression, because if it doesn't return something, the return value will be undefined which of course will error break the component rendering:

export default function myComponent(props) {
  return (
    <div>
      {do {
        if ([condition]) {
          <p>If statement is true</p>
        }
        null
      }}
      <p>I am always rendered</p>
    </div>
  );
}

Or, use the Nullish coalescing operator ?? which will also catch undefined:

export default function myComponent(props) {
  return (
    <div>
      {do {
        if ([condition]) {
          <p>If statement is true</p>
        }
      } ?? null}
      <p>I am always rendered</p>
    </div>
  );
}

Other answers here suggest why bother using do expression since we can do this using the Conditional (ternary) operator ?:, and the answer is that using the ternary operator when we'll have more than one condition won't be syntactical friendly and it will lead in miss-renders and hard time understanding the logic for developers:

export default function myComponent(props) {
  return (
    <div>
      {[condition1]
        ? <p>If condition1 is true</p> :
       [condition2]
        ? <p>If condition2 is true</p> :
       [condition2]
        ? <p>If condition3 is true</p> :
       [condition4]
        ? <p>If condition4 is true</p> :
        null
      }
      <p>I am always rendered</p>
    </div>
  );
}

and that's one of the reasons behind the proposal and existence of the do expression; it will make multiple conditional expressions syntactical friendly:

export default function myComponent(props) {
  return (
    <div>
      {do {
        if ([condition1]) <p>If condition1 is true</p>
        if ([condition2]) <p>If condition2 is true</p>
        if ([condition3]) <p>If condition3 is true</p>
        if ([condition4]) <p>If condition4 is true</p>
      } ?? null}
      <p>I am always rendered</p>
    </div>
  );
}
Christos Lytras
  • 36,310
  • 4
  • 80
  • 113
  • It looks like this is no longer true in the latest version of the do expressions [proposal](https://github.com/tc39/proposal-do-expressions#limitations), and explicitly writing `else` is more readable anyway. But this answer is a great explanation of why you'd want to use a do expression. – Matt Browne Mar 17 '22 at 11:45
2

You can do it simply, using conditioanl rendering:

    {condition && jsx-element}

Example:

    {relationshipStatus===RelationshipStatus.SINGLE && <ShowIAmSingleComponent />}

Whenever this relationshipStatus takes value of RelationshipStatus.SINGLE, it will render this ShowIAmSingleComponent component.

Simple as react.

Maifee Ul Asad
  • 3,992
  • 6
  • 38
  • 86