React學習:條件渲染
React 中的條件渲染就和在 JavaScript 中的條件語句一樣。通過 JavaScript 條件操作符(如 if ) 根據不同的條件 來決定建立渲染不同的元素
,並且讓 React 更新匹配的 UI 。
仔細閱讀程式碼,你會發現這一章對你收穫最大的是怎麼讓程式碼寫的更簡單優雅。
一、怎麼用
看下面dome就懂了,順便看看我們 在多個頁面寫react 與 在一個頁面寫react的區別
例:多個頁面
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
let obj = {name:'bty',age:12}; //資料
ReactDOM.render(<App {...obj}/>, document.getElementById('root'));
App.js
import React, { Component } from 'react';
import Greeting from './Greeting';
class App extends Component {
constructor(props){
super(props);
this.state = {
isLoggedIn:false
};
}
handle = () => {
this.setState(prevState => ({
isLoggedIn: !prevState.isLoggedIn
}));
}
render(){
let isLoggedIn = this.state.isLoggedIn;
return (<div>
<Greeting isLoggedIn={isLoggedIn} name={this.props.name}/>
<button onClick={this .handle}>
{isLoggedIn ? '退出登入' : '登入'}
</button>
</div>
);
}
}
export default App;
Greeting.js
import React, {Component} from 'react';
class Greeting extends Component{
render(){
let {name,isLoggedIn} = {...this.props};
let text = isLoggedIn ? ('welcome you ,' + name + '!')
: 'please login!';
return (
<div>
{text}
</div>
);
}
}
export default 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) {
//用變數來儲存react元素
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
function UserGreeting(props) {
return <h1>welcome you ,{props.name}</h1>;
}
function GuestGreeting(props) {
return <h1>please login!</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting name={'bty'}/>;
}
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')
);
執行效果:同上
二、內聯 if 用法
1、boolean && expression
我們可以 在JSX中嵌入任何表示式 ,方法是將表示式包裹在 {} 中。
下面表示式可以正常執行,是因為在 JS 中, true && expression 總是會評估為 expression ,而 false && expression 總是執行為 false 。
因此,如果條件為 true ,則 && 後面的元素將顯示在輸出中。 如果是 false,React 將會忽略並跳過它。
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')
);
輸出:
Hello!
You have 3 unread messages.
注意:
0 && expression ,expression仍然會被渲染。例如,這段程式碼不會按照你預期的發生,因為當 props.messages 是一個空陣列時 0 會被列印:
<div>
{props.messages.length &&
<MessageList messages={props.messages} />
}
</div>
要修復這個問題,確保 && 之前的表示式總是布林值:
<div>
{props.messages.length > 0 &&
<MessageList messages={props.messages} />
}
</div>
2、condition ? true : false
使用 JavaScript 的條件操作符 condition ? true : false
小技巧:可以這些寫,來簡化程式碼
let boolean = true; let a = !boolean;
效果等價於 let boolean = true; let a = boolean ?false : true;
在下面這個例子中,我們使用它來進行條件渲染一個小的文字塊:
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>
);
}
三、防止元件渲染
有時,你可能希望隱藏某個元件,即使它是由另一個元件渲染的。
為此,我們可以return null,而不是其渲染輸出。
從元件的 render 方法返回 null 不會影響元件生命週期方法的觸發。 例如, componentWillUpdate 和 componentDidUpdate 仍將被呼叫。
在下面的例子中,根據名為warn的 prop 值,呈現 < WarningBanner/> 。如果 prop 值為 false ,則該元件不渲染:
function Warning(props){
let warn = props.warn
?
<div className='warning'>Warning!</div>
:
null;
return warn;
}
class Page extends React.Component {
constructor(props){
super(props);
this.state = {
showWarning:true
};
}
handle = () => {
this.setState(prevState => ({
showWarning:!prevState.showWarning
}));
}
render(){
let showWarning = this.state.showWarning;
return(
<div>
<Warning warn={showWarning} />
<button onClick={this.handle}>
{showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
/* css */
.warning {
background-color: red;
text-align: center;
width: 100%;
padding: 10px;
color: white;
}
輸出結果:
點選Hide後
再點選show又回到第一張圖