How to do a nested if else statement in ReactJS JSX?
Solution 1
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
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
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 4
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 5
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>
)
Related videos on Youtube
ALM
Updated on January 30, 2022Comments
-
ALM over 2 years
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
-
Pointy almost 8 yearsjust fyi
if
/else
constructs aren't "loops" -
Felix Kling almost 8 yearsThe
(<div>body</div>)
part doesn't seem to belong to anything. That's an error. Otherwise what you have seems fine. -
ALM almost 8 years@FelixKling If I do it as <div>body<div> it will not work. The point is I want to have some data in the else that is always shown and another if for the title.
-
Felix Kling almost 8 yearsI understand, but
foo ? bar : baz abc
is not valid JavaScript. You want<div>{this.state.someBoolean ? ... : ...}<div>body</div></div>
then. -
Felix Kling almost 8 yearsYou cannot have two expressions after each other:
4 5
is simply invalid. That's not a problem for statements. -
Felix Kling almost 8 yearsMaybe that's your confusion:
foo ? bar : baz abc
is interpreted as(foo ? bar : baz) (abc)
not asfoo ? bar : (baz abc)
. But both are invalid anyway. -
Felix Kling almost 8 yearsRe "Updated as solution below but this will still not render." I missed
{...}
in my code, you can see the updated version in my code. Also please don't don't change your original question, because my answer doesn't make sense now anymore (I rolled back your edit). -
ALM almost 8 yearsThe original code is not the issue, the problem is I still do not see how to nest another condition within the initial if (X) ? a : b ( nested if (y) (title) main)
-
-
ALM almost 8 yearsThe problem is that I only want body to show up in some other title. Using "body" might not have been the best choice. I can rewrite
-
Felix Kling almost 8 yearsThen your original code makes even less sense and doesn't mat your
if...else
example.What you want isthis.state.someBoolean ? (<div>some title</div>):(<div><div>some other title</div><div>body</div></div>)
then. -
ALM almost 8 yearsThe thing is that I only want to show the title if another condition is true. The body will be shown as you have in the second example in the else section but then I need ANOTHER conditional on the title. The page shows either, A loading page OR a main page with or without a title
-
ALM almost 8 yearsI updated my question with your example plus the additional conditional
-
Felix Kling almost 8 yearsUpdated my answer. Note that all the examples only show the false branch of the outer conditional, because that's the only thing that was incorrect. If this is still not what you want, I really have no idea what you are talking about.
-
ALM almost 8 yearsLet us continue this discussion in chat.
-
ALM almost 8 yearsI updated the question to include what I originally asked about how to put a nested conditional inside another conditional. I would like to display a loading page or main page but in the main page it needs a condition on if it has a title, hence the nested conditional. I updated your solution with the additional condition .
-
Felix Kling almost 8 yearsSo you already have the outer conditional,
{a ? b : c}
. You simply take my last example and replacec
with it. As I said, only the false branch of the outer conditional is incorrect. Your outer conditional is fine and hence I haven't repeated it. Or in more concrete terms: Replace the linethis.otherCondition && <div>title</div>
in your updated example with{this.state.someBoolean ? (<div>some title</div>) : null}
from my example. -
ALM almost 8 yearsThank you for your help. In the end it turns out I had something else causing the runtime error. I made the changes you selected and it works.
-
ALM almost 8 yearsI ended up using your second solution with renderContent as I do believe it easier to read and use. Thank you
-
dipole_moment over 5 years"prettiest" solution in here but from a performance perspective, this will add some overhead since an IIFE is created every time a render gets invoked.
-
dehumanizer over 5 yearsIf you need a conditional rendering, it doesn't really matter wether it's IIFE or nested ternaries (which I grew to like since posting my original answer), or
R.cond([...])
. If anything, the "bigger" performance impact is the inline function creation. But in the big picture, it's a premature performance optimization and you'd be better off using PureComponent or ShouldComponentUpdate. My answer differs from the accepted answer mostly in the fact that you don't have to create a class member function that you won't use anywhere else and can just do it inline. -
andromeda over 2 yearsThis is so good. Exactly what I was looking for.
-
sashiksu over 2 yearswhen using [] for rendering react throw warning of each child component should have a key prop.
-
GonEbal over 2 yearsYou should use <></> (<React.Fragment>) instead of [].
-
Neal Ehardt over 2 yearsRight. Updated.