在React中 ,你可以创建封装了你所需要行为的不同组件,接着,你也能根据应用的状态,来选择渲染这些组件的部分行为。

根据条件渲染在React中的工作方式类似JavaScript。用JavaScript的操作符像:if或条件运算符来创造一些表征当前状态的元素,从而更新相关UI界面。

看看这两个组件:

  1. function UserGreeting(props) {
  2. return <h1>Welcome back!</h1>;
  3. }
  4. function GuestGreeting(props) {
  5. return <h1>Please sign up.</h1>;
  6. }

我们创建了这个‘greeting’组件,是呈现UserGreeting还是呈现GuestGreeting取决于用户的登录状态:

  1. function Greeting(props) {
  2. const isLoggedIn = props.isLoggedIn;
  3. if (isLoggedIn) {
  4. return <UserGreeting />;
  5. }
  6. return <GuestGreeting />;
  7. }
  8. ReactDOM.render(
  9. // Try changing to isLoggedIn={true}:
  10. <Greeting isLoggedIn={false} />,
  11. document.getElementById('root')
  12. );

这个例子渲染了不同的‘greeting’,根据的就是isLoggedIn这个属性的值。

元素变量

你可以用变量来储存一个元素。这样在组件中那些不需要变更的部分维持现状是,能帮助你条件性渲染组件(需要变更)的部分。

看看这两个新的组件,Logout登出和Login登入按钮:

  1. function LoginButton(props) {
  2. return (
  3. <button onClick={props.onClick}>
  4. Login
  5. </button>
  6. );
  7. }
  8. function LogoutButton(props) {
  9. return (
  10. <button onClick={props.onClick}>
  11. Logout
  12. </button>
  13. );
  14. }

接着我们创建一个‘状态满满’的组件:LoginControl。

该组件会渲染和当中的一个,渲染谁取决于当前它的状态。它也渲染了之前的例子组件:

  1. class LoginControl extends React.Component {
  2. constructor(props) {
  3. super(props);
  4. this.handleLoginClick = this.handleLoginClick.bind(this);
  5. this.handleLogoutClick = this.handleLogoutClick.bind(this);
  6. this.state = {isLoggedIn: false};
  7. }
  8. handleLoginClick() {
  9. this.setState({isLoggedIn: true});
  10. }
  11. handleLogoutClick() {
  12. this.setState({isLoggedIn: false});
  13. }
  14. render() {
  15. const isLoggedIn = this.state.isLoggedIn;
  16. let button = null;
  17. if (isLoggedIn) {
  18. button = <LogoutButton onClick={this.handleLogoutClick} />;
  19. } else {
  20. button = <LoginButton onClick={this.handleLoginClick} />;
  21. }
  22. return (
  23. <div>
  24. <Greeting isLoggedIn={isLoggedIn} />
  25. {button}
  26. </div>
  27. );
  28. }
  29. }
  30. ReactDOM.render(
  31. <LoginControl />,
  32. document.getElementById('root')
  33. );

声明一个变量而且使用if语句是一个不错的方法来达到条件化渲染组件的目的,有时候你可能想用更简短的语法。下面介绍下载JSX中的行内条件判断。

行内的IF和逻辑&&操作符

任何JSX只要写在花括号里都是可嵌入的。这里面包括了JavaScript的’&&’(且运算符) 。这对于行内条件元素可能比较方便:

  1. function Mailbox(props) {
  2. const unreadMessages = props.unreadMessages;
  3. return (
  4. <div>
  5. <h1>Hello!</h1>
  6. {unreadMessages.length > 0 &&
  7. <h2>
  8. You have {unreadMessages.length} unread messages.
  9. </h2>
  10. }
  11. </div>
  12. );
  13. }
  14. const messages = ['React', 'Re: React', 'Re:Re: React'];
  15. ReactDOM.render(
  16. <Mailbox unreadMessages={messages} />,
  17. document.getElementById('root')
  18. );

这样之所以奏效,是因为在JavaScript中,true && 表达式 ,值永远等于表达式,且false && 表达式 永远等于false。

因此,要是条件的值是true(成立),那么&&右边的元素就会被输出;条件不成立,React就会忽略和跳过右边的。

行内的If-Else 使用条件运算符

条件化的行内渲染的另一种方法是使用JavaScript的三目运算符 condition ? true : false。

下面的例子中我们就用这种写法条件化渲染了一小段文字:

  1. render() {
  2. const isLoggedIn = this.state.isLoggedIn;
  3. return (
  4. <div>
  5. The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
  6. </div>
  7. );
  8. }

它也能用于更大的表达式,尽管它也不太清楚发生什么:

  1. render() {
  2. const isLoggedIn = this.state.isLoggedIn;
  3. return (
  4. <div>
  5. {isLoggedIn ? (
  6. <LogoutButton onClick={this.handleLogoutClick} />
  7. ) : (
  8. <LoginButton onClick={this.handleLoginClick} />
  9. )}
  10. </div>
  11. );
  12. }

就像JavaScript,选哪一种风格是取决于你和你的团队认为哪一种风格可读性强,这由你决定。但也要记得,任何时候,条件太多太复杂,那么这时候就是提取组件的好时机。

防止组件渲染

少数情况下,你可能想要组件吧自己隐藏,即使组件本身被其他组件渲染着。这样你需要return null 来替代组件本身的输出。

下面的例子中,被渲染与否决定于一个叫warn属性props。如果这个prop属性值为false,那么这个组件将不会被渲染。

  1. function WarningBanner(props) {
  2. if (!props.warn) {
  3. return null;
  4. }
  5. return (
  6. <div className="warning">
  7. Warning!
  8. </div>
  9. );
  10. }
  11. class Page extends React.Component {
  12. constructor(props) {
  13. super(props);
  14. this.state = {showWarning: true}
  15. this.handleToggleClick = this.handleToggleClick.bind(this);
  16. }
  17. handleToggleClick() {
  18. this.setState(prevState => ({
  19. showWarning: !prevState.showWarning
  20. }));
  21. }
  22. render() {
  23. return (
  24. <div>
  25. <WarningBanner warn={this.state.showWarning} />
  26. <button onClick={this.handleToggleClick}>
  27. {this.state.showWarning ? 'Hide' : 'Show'}
  28. </button>
  29. </div>
  30. );
  31. }
  32. }
  33. ReactDOM.render(
  34. <Page />,
  35. document.getElementById('root')
  36. );

从一个组件的render的方法返回null不会影响第一个生命周期方法。举例来说,componentWillUpdate和componentDidUpdate依然会被调用。

官网文章 Quick Start :Conditional Rendering