React版本:15.4.2
**翻譯:xiyoki **
在React中儿礼,你可以創(chuàng)建許多不同的組件指蚜,這些組件封裝了你所需要的行為献起。然后,你可以僅渲染其中的一些祷杈,具體取決于應(yīng)用程序的state斑司。
React中的條件渲染與Javascript中的條件的工作方式相同。使用Javascript操作符但汞,例如if
或條件操作符來創(chuàng)建一個(gè)表示當(dāng)前state的元素宿刮,然后讓React匹配它們,并更新UI特占。
考慮這兩個(gè)組件:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
我們將創(chuàng)建一個(gè)Greeting
組件糙置,它的展現(xiàn)將取決于用戶是否登錄云茸。
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
這個(gè)例子是目,根據(jù)isLoggedIn
的屬性值渲染了不同的歡迎辭。
Element Variables(元素變量)
你可以使用變量來存儲元素标捺。這可以幫助你有條件地渲染組件的一部分懊纳,而組件其余的輸出不會改變揉抵。
考慮這兩個(gè)代表注銷和登錄按鈕的新組件:
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
在下面的例子中,我們將創(chuàng)建一個(gè)有state的組件嗤疯,叫LoginControl
冤今。
它將根據(jù)其當(dāng)前的state渲染<LoginButton />
和 <LogoutButton />
中任意一個(gè)。它也會渲染來自前一個(gè)例子的<Greeting />
茂缚。
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
let button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
雖然聲明一個(gè)變量戏罢,并且使用if
語句來有條件地渲染組件是一個(gè)很好的方式,然而有時(shí)你可能需要使用更短的語法脚囊。有幾種在JSX中內(nèi)聯(lián)條件的方法龟糕,如下所述。
Inline If with Logical && Operator(使用邏輯&&運(yùn)算符內(nèi)聯(lián)if語句)
你可以在JSX中內(nèi)嵌任何用{}
包裹的表達(dá)式悔耘。這包括Javascript中的邏輯&&
運(yùn)算符讲岁。它可以很方便地有條件地包括一個(gè)元素:
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
它之所以工作是因?yàn)樵贘avaScript中, true && expression
總是計(jì)算為expression
, 而false && expression
總是計(jì)算為false
。
因此衬以,如果條件是true
缓艳,那么剛好在&&
符右邊的元素將會出現(xiàn)在輸出中。如果是false
看峻,React會忽略并跳過它阶淘。
Inline If-Else with Conditional Operator(使用條件操作符內(nèi)聯(lián)if-else 語句)
在行內(nèi)有條件地渲染元素的另一種方法是使用Javascript的三元運(yùn)算符condition ? true : false
。
在下面的例子中互妓,我們使用它來有條件地渲染一小塊文本舶治。
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
它也可以用于較大的表達(dá)式,雖然發(fā)生了什么會不太明顯:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
就像在Javascript中一樣车猬,你可以基于你和你的團(tuán)隊(duì)對可讀寫性的考慮霉猛,自主地選擇一個(gè)適當(dāng)?shù)娘L(fēng)格。 當(dāng)條件變得過于復(fù)雜時(shí)珠闰,不要忘了這可能是一個(gè)提取組件的好時(shí)機(jī)惜浅。
Preventing Component from Rendering(阻止組件渲染)
在極少的情況下,你可能希望組件隱藏自身伏嗜,即使它已由另一個(gè)組件渲染坛悉。通過返回null
,而不是返回渲染輸出承绸,即可隱藏組件自身裸影。
在下面的例子中,<WarningBanner />
的渲染依賴于warn
屬性的值军熏,如果屬性值是false
,那么組件將不會渲染轩猩。
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {showWarning: true}
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(prevState => ({
showWarning: !prevState.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
從組件的render
方法中返回null
,并不會影響組件生命周期方法的觸發(fā)。例如均践,componentWillUpdate
和 componentDidUpdate
依然會被調(diào)用晤锹。