React Conditional Rendering (條件渲染)
在 React 有幾種條件式的寫法,讓你用來判斷在不同的資料條件下,分別該返回哪一個對應的 UI 畫面。
JavaScript if else
| 三元運算子 ? :
你可以使用 JavaScript 的 if 或三元運算子 (Conditional (ternary) Operator)。
例如顯示登入狀態的元件:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
// 如果已登入,返回 <UserGreeting /> UI
if (isLoggedIn) {
return <UserGreeting />;
}
// 如果未登入,返回 <GuestGreeting /> UI
return <GuestGreeting />;
}
ReactDOM.render(
// isLoggedIn (true/false) props 用來控制目前是否登入
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
上面的 Greeting 也可以寫成:
function Greeting(props) {
return props.isLoggedIn ? <UserGreeting /> : <GuestGreeting />;
}
Element Variables
如果只有畫面的一部分會變動時,你也可以將元素先放到變數裡面,當作一個動態值供後續渲染。
例子:
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;
// 根據目前 isLoggedIn 狀態,將對應的按鈕 UI 元素先存在 button 變數中
let button = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
// 可以直接在元件的 JSX 中引用這個變數
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
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 />;
}
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
Inline &&
邏輯運算子
你可以在 JSX 的 { }
中使用 &&
Logical Operator。
語法是:
{條件式 && 元素}
如果條件式是 true
則顯示元素,反之 false
則不顯示東西。
例子:
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
// 如果有未讀信件 unreadMessages.length,則顯示未讀訊息
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')
);
Inline 三元運算子 ? :
你可以在 JSX 的 { }
中使用 三元運算子 ? :
。
語法是:
{條件式 ? 當條件是為真顯示的元素 : 當條件是為否顯示的元素}
例如:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
上面的括號 ( ) 是為了可讀性,你拿掉也不會有錯誤,不要忘記 JSX 只是一個 JavaScript expression。
不要顯示元素
在某些條件下,你會希望元件不要顯示任何東西,很簡單,你就直接從元件的 render()
方法 return null
或 false
。
// 如果是 functional component 沒有 render()
// 一樣是直接用 return null
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')
);