How to do a nested if else statement in ReactJS JSX?

JavascriptReactjsEcmascript 6Jsx

Javascript Problem Overview


I wanted to know if its possible to do nested if else if in ReactJS JSX?

I have tried various different ways and I am unable to get it to work.

I am looking for

if (x) {
  loading screen
} else {
  if (y) {
    possible title if we need it
  }
  main 
}

I have tried this but I can not get it to render. I have tried various ways. It always breaks once I add the nested if.

{
  this.state.loadingPage ? (
    <div>loading page</div>
  ) : (
    <div>
      this.otherCondition && <div>title</div>
      <div>body</div>
    </div>
  );
}

Update

I ended up choosing the solution to move this to renderContent and call the function. Both of the answers did work though. I think I may use the inline solution if it is for a simple render and renderContent for more complicated cases.

Thank you

Javascript Solutions


Solution 1 - Javascript

You need to wrap your title and body in a container. That could be a div. If you use a fragment instead, you'll have one less element in the dom.

{ this.state.loadingPage
  ? <span className="sr-only">Loading... Registered Devices</span>
  : <>
      {this.state.someBoolean
        ? <div>some title</div>
        : null
      }
      <div>body</div>
    </>
}

I would advise against nesting ternary statements because it's hard to read. Sometimes it's more elegant to "return early" than to use a ternary. Also, you can use isBool && component if you only want the true part of the ternary.

renderContent() {
  if (this.state.loadingPage) {
    return <span className="sr-only">Loading... Registered Devices</span>;
  }

  return (
    <>
      {this.state.someBoolean && <div>some title</div>}
      <div>body</div>
    </>
  );
}

render() {
  return <div className="outer-wrapper">{ this.renderContent() }</div>;
}

Caveat to the syntax someBoolean && "stuff": if by mistake, someBoolean is set to 0 or NaN, that Number will be rendered to the DOM. So if the "boolean" might be a falsy Number, it's safer to use (someBoolean ? "stuff" : null).

Solution 2 - Javascript

Instead of nesting ternary operators as it is often suggested or creating a separate function that will not be reused anywhere else, you can simply call an inline expression:

<div className="some-container">
{
   (() => {
       if (conditionOne)
          return <span>One</span>
       if (conditionTwo)
          return <span>Two</span>
       else (conditionOne)
          return <span>Three</span>
   })()
}
</div>

Solution 3 - Javascript

You can check multiple conditions to render components accordingly like below:

  this.state.route === 'projects'
  ? 
  <div> <Navigation onRouteChange={this.onRouteChange}/> Projects</div>
  :
  this.state.route === 'about'
  ?
  <div> <Navigation onRouteChange={this.onRouteChange}/> About</div>
  :
  this.state.route === 'contact'
  ?
  <div> <Navigation onRouteChange={this.onRouteChange}/> Contact</div>
  :
  <p> default </p>

Solution 4 - Javascript

You can nest as many statements as possible. please follow this code assuming that this.state.firstTestValue, this.state.someTestValue and this.state.thirdValueTest are your test values from the state.

{this.state.firstTestValue
    ? <div >First Title</div>
    : [
        this.state.someTestValue
            ? <div>Second Title</div>
            : [
                this.state.thirdValueTest 
                ? <div>Some Third Title</div> 
                : <div>Last Title</div>
            ]
    ]
}

Solution 5 - Javascript

Your code in the alternative is not valid JavaScript/JSX expression:

(
  this.state.someBoolean ?
  (<div>some title</div>):(<div>some other title</div>)
  <div>body</div>
)

Lets simplify this to

(
  true ? 42 : 21
  3
)

This throws the error

> Uncaught SyntaxError: Unexpected number(…)

You cannot just have two expression next to each other.

Instead you have to return a single value from the false branch of the conditional operator. You can do this by simply putting it in another JSX element:

(
  <div>
    {this.state.someBoolean ? (<div>some title</div>) : (<div>some other title</div>)}
    <div>body</div>
  </div>
)

If you want to only show "body" when "some other title" is shown, you need to move <div>body</div> into the false branch of the conditional operator:

(
  this.state.someBoolean ?
    (<div>some title</div>) :
    (<div>
       <div>some other title</div>
       <div>body</div>
    </div>)
)

Or maybe you want

(
  <div>
    {this.state.someBoolean ? (<div>some title</div>) : null}
    <div>body</body>
  </div>
)

Solution 6 - Javascript

As the other answer suggest, there are various ways to do a nested if else in react. Which one to use depends on situation and preferences.

In my opinion, for best code readability, on this occassion it'd be best to move the content of else to separate function:

renderContent() {
     return (
         <div>
             { this.otherCondition && <div>title</div> }
             <div>body</div>
         </div>
     );
}

render() {
    return (
        <div>
            { ... }
            {
                this.state.loadingPage ?
                    <div>loading page</div>
                    :
                    this.renderContent()
            }
            { ... }
        </div>
    )
}

Or if it's simple enough (in case no other elements are rendered), I'd go with:

render() {
    if (this.state.loadingPage) {
        return (
            <div>loading page</div>
        )
    }
    return (
        <div>
            { this.otherCondition && <div>title</div> }
            <div>body</div>
        </div>
    );
}

Here's an article on conditional rendering in React, so please check it out if you're interested in more details on this topic.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionALMView Question on Stackoverflow
Solution 1 - JavascriptNeal EhardtView Answer on Stackoverflow
Solution 2 - JavascriptdehumanizerView Answer on Stackoverflow
Solution 3 - JavascriptAkshata DabadeView Answer on Stackoverflow
Solution 4 - JavascriptBryan AustinView Answer on Stackoverflow
Solution 5 - JavascriptFelix KlingView Answer on Stackoverflow
Solution 6 - JavascriptNesha ZoricView Answer on Stackoverflow