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

来源:互联网 发布:linux查数据库相互命令 编辑:程序博客网 时间:2024/06/13 10:13

在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仍被调用。