1. 程式人生 > >7.React中文之有條件的渲染

7.React中文之有條件的渲染

在React中,你可以建立囊括你需要的行為的明確的元件。而後,你根據應用的狀態僅渲染元件中的一些。

在React中有條件的渲染同在JavaScript中條件使用一樣。使用JavaScript操作符像if或者條件操作符建立代表當前狀態的元素,讓React把相應的他們更新到UI中。

考慮這兩個元件:

function UserGreeting(props){

    return <h1>Welcome back!</h1>

}

function GuestGreeting(props){

    return <h1>Please sign up.</h1>

}

我們依據使用者是否登入,建立展示這兩個元件中的一個Greeting元件。

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')

);

在CodePen上試試吧。

這個例子基於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')

);

在CodePen上試試吧。

宣告變數和使用if語句是有條件地渲染元件的一個好的方法,有時你可能想用一個更短的語法。在JSX中有幾個內斂條件的方法,如下所示:

邏輯&&運算子的內聯if

在JSX中,你可以用大括號擴住表示式。包含邏輯&&運算子。有條件地包含一個元素很方便:

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 message=['React','Re:React','Re:Re:React'];

ReactDOM.render(

    <Mailbox unreadMessages={messages} />,

     document.getElementById('root')

);

在CodePen上試試吧。

這樣寫有效,是因為在JavaScript中,true&&expression 總會求expression的值,而false&&expression計算值總是false。

因此,如果條件正確,&&後的元素會出現在輸出中。如果條件不正確,React將忽略並跳過它。

條件運算子的內聯If-Else

有條件地渲染元素的另一個內聯方法是使用JavaScript條件操作符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>

   );

}

像用JavaScript一樣,選擇什麼更具可讀性的合適的方式取決於你。還要記得條件變得很複雜是提取元件的好時機。

阻止元件渲染

在極少數情況下,儘管元件被另一個元件渲染,但是它需要隱藏自己。為了實現這樣的效果,代替它的渲染輸出返回null。

在以下例子中,<WarningBanner />基於warn屬性值渲染。如果該屬性值是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.showWaring} />

                     <button onClick={this.handleToggleClick}>

                           {this.state.showWarning?'Hide':'Show'}

                     </button>

                </div> 

         ); 

   }

}

ReactDOM.render(

   <Page />,

   document.getElementById('root')

);

在CodePen中試試吧。

元件render方法返回null不影響元件生命週期方法的點燃。例如,componentWillUpdate和componentDidUpdate仍被呼叫。