7.React中文之有條件的渲染
在React中,你可以建立囊括你需要的行為的明確的元件。而後,你根據應用的狀態僅渲染元件中的一些。
在React中有條件的渲染同在JavaScript中條件使用一樣。使用JavaScript操作符像if或者條件操作符建立代表當前狀態的元素,讓React把相應的他們更新到UI中。
考慮這兩個元件:
function UserGreeting(props){
return <h1>Welcome back!</h1>
}
function GuestGreeting(props){
return <h1>Please sign up.</h1>
}
我們依據使用者是否登入,建立展示這兩個元件中的一個Greeting元件。
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')
);
在CodePen上試試吧。
這個例子基於isLoggedIn屬性值渲染不同的問候。
元素變數
你可以使用變數儲存元素。這將幫你在輸出的其他部分沒有變化的情況下,有條件地渲染元件的一部分。
考慮表示退出和登陸按鈕的這兩個新元件:
function LoginButton(props){
return(
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props){
return(
<button onClick={props.onClick}>
Logout
</button>
);
}
在以下的例子中,我們將建立叫LoginControl的有狀態的元件。
依賴它的當前狀態,渲染<LoginButton />或者<LogoutButton />。它也渲染之前例子中的<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>
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
在CodePen上試試吧。
宣告變數和使用if語句是有條件地渲染元件的一個好的方法,有時你可能想用一個更短的語法。在JSX中有幾個內斂條件的方法,如下所示:
邏輯&&運算子的內聯if
在JSX中,你可以用大括號擴住表示式。包含邏輯&&運算子。有條件地包含一個元素很方便:
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 message=['React','Re:React','Re:Re:React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
在CodePen上試試吧。
這樣寫有效,是因為在JavaScript中,true&&expression 總會求expression的值,而false&&expression計算值總是false。
因此,如果條件正確,&&後的元素會出現在輸出中。如果條件不正確,React將忽略並跳過它。
條件運算子的內聯If-Else
有條件地渲染元素的另一個內聯方法是使用JavaScript條件操作符condition ?true:false.
以下,我們用它有條件地渲染文字的一部分:
render(){
const isLoggedIn=this.state.isLoggedIn;
return(
<div>
The user is <b>{isLoggedIn?'currently':'not'}</b> logged in.
</div>
);
}
也可用在更大的表示式中,只是什麼將執行就不怎麼明確了:
render(){
const isLoggedIn=this.state.isLoggedIn;
return(
<div>
{isLoggedIn?(
<LogoutButton onClick={this.handleLogoutClick} />
):(
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
像用JavaScript一樣,選擇什麼更具可讀性的合適的方式取決於你。還要記得條件變得很複雜是提取元件的好時機。
阻止元件渲染
在極少數情況下,儘管元件被另一個元件渲染,但是它需要隱藏自己。為了實現這樣的效果,代替它的渲染輸出返回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.showWaring} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning?'Hide':'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
在CodePen中試試吧。
元件render方法返回null不影響元件生命週期方法的點燃。例如,componentWillUpdate和componentDidUpdate仍被呼叫。