如何在 ReactJSJSX 中执行嵌套的 if else 语句?

我想知道在 ReactJSJSX 中是否可以做嵌套的 if else?

我已经尝试了各种不同的方法,但我无法让它起作用。

我正在寻找

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

我已经试过了,但我不能得到它渲染。我试过各种方法。一旦我添加嵌套的 if,它总是中断。

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

更新

最后,我选择了将其移动到 renderContent 并调用函数的解决方案。不过,这两个答案都起作用了。我认为我可以使用内联解决方案,如果它是一个简单的渲染和渲染内容为更复杂的情况下。

谢谢你

134657 次浏览

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>
)

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).

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>

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.

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>

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>
]
]
}