1. 程式人生 > >React學習:條件渲染

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又回到第一張圖