react 入坑筆記(五) - 條件渲染和列表渲染
阿新 • • 發佈:2018-11-19
條件渲染和列表渲染
一、條件渲染
條件渲染較簡單,使用 JavaScript 操作符 if 或條件運算子來建立表示當前狀態的元素,然後讓 React 根據它們來更新 UI。
貼一個小栗子:
function UserGreeting(props) { return <h1>歡迎回來!</h1>; } function GuestGreeting(props) { return <h1>請先註冊。</h1>; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } ReactDOM.render( // 嘗試修改 isLoggedIn={true}: <Greeting isLoggedIn={false} />, document.getElementById('example') );
當然,得益於 jsx 的語法,我們可以用變數來快取元素或者元件:
function UserGreeting(props) { return <h1>歡迎回來!</h1>; } function GuestGreeting(props) { return <h1>請先註冊。</h1>; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } function LoginButton(props) { return ( <button onClick={props.onClick}> 登陸 </button> ); } function LogoutButton(props) { return ( <button onClick={props.onClick}> 退出 </button> ); } 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('example') );
阻止渲染的栗子:
function WarningBanner(props) { if (!props.warn) { return null; // 必須寫 null,不寫執行會報錯 } return ( <div className="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 ? '隱藏' : '顯示'} </button> </div> ); } } ReactDOM.render( <Page />, document.getElementById('example') );
注意:元件的 render 方法返回 null 並不會影響該元件生命週期方法的回撥。例如,componentWillUpdate 和 componentDidUpdate 依然可以被呼叫。
二、列表渲染
列表渲染可以使用 js 中的 .map() 來進行。(map 返回一個經過邏輯處理的新陣列)
function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <li key={number.toString()}> {number} </li> ); return ( <ul>{listItems}</ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('example') );
和 vue 相同,需要給每個列表元素繫結一個 key,便於 React 識別哪些元素髮生了變化。
function ListItem(props) { return <li>{props.value}</li>; } function NumberList(props) { const numbers = props.numbers; const listItems = numbers.map((number) => <ListItem key={number.toString()} value={number} /> ); return ( <ul> {listItems} </ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('example') );
注意:key 會作為給 React 的提示,但不會傳遞給元件,因此,元件並不會知道傳遞給它的 key。
在 jsx 中使用 map():
function ListItem(props) { return <li>{props.value}</li>; } function NumberList(props) { const numbers = props.numbers; return ( <ul> {numbers.map((number) => <ListItem key={number.toString()} value={number} /> )} </ul> ); } const numbers = [1, 2, 3, 4, 5]; ReactDOM.render( <NumberList numbers={numbers} />, document.getElementById('example') );
對比一下,只是少了宣告 listItems 語句,並把後面的 map() 搬到 jsx 中。