在React中,你可以創建不同的組件各自封裝你需要的東西。之后你可以只渲染其中的一部分,這取決於應用的state(狀態)。
條件渲染在React里就和js里的條件語句一樣。使用js里的if或者條件表達式創建元素來顯示當前的狀態,然后讓React來更新UI。
看看下面兩個組件:
function UserGreeting(props) { return <h1>Welcome back!</h1>; } function GuestGreeting(props) { return <h1>Please sign up.</h1>; }
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') );
根據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') );
聲明一個變量並且使用if語句是一個條件渲染組件的好方法,有時你可能想用一個更簡短的語法。在JSX里有很多方法來在行間使用條件,請往下面看相關介紹。
行內條件使用&&操作符
也許你會通過將表達式包在花括號里在JSX里嵌入表達式。這就包括了使用js里的&&操作符。這樣可以很方便的來表示元素渲染的條件:
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') );
在js里,true && expression的結果總會是expression,false && expression的結果總會是false。
因此,如果條件是true,在&&右邊的元素就會在輸出里。如果條件是false,React就會忽略它。
行內條件使用三目運算符
另外一個方法來條件渲染元素就是在行間使用js三目運算符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> ); }
就像在js里一樣,這取決於你選擇一個合適的風格基於你和你的團隊覺得哪一種可讀性好。但也要記得無論何時狀況變得太復雜,那最好去從中提取組件。
阻止組件渲染
有一些情況也許你希望一個組件隱藏起來即使它依靠別的組件渲染。想要隱藏它就返回null作為輸出而不是渲染輸出。
下面這個例子,<WarningBanner />依賴於prop的值warn來渲染。如果prop的值是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') );