Skip to content

条件渲染

在React中,你可以创建不同的组件来封装各种你需要的行为。然后依据应用的不同状态,你可以只渲染对应状态下的部分内容。

React中的条件渲染和javaScript中的一样,使用JavaScript运算符if或者条件运算符去创建元素来表现当前的状态,然后让React根据他们来更新UI。

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

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

根据props渲染组件:

function UserGreeting (props) {
    return <h1>Welcome back!</h1>;
}

function GuestGreeting (props) {
    return <h1>Please sign up.</h1>;
}

// function Greeting (props) {
//     const isLoggedIn = props.isLoggedIn;
//     if (isLoggedIn) {
//         return <UserGreeting  />;
//     }
//     return <GuestGreeting  />;
// }

class Greeting extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            isLoggedIn: props.isLoggedIn
        }
        // console.log(this.isLoggedIn)
        // this.isLoggedIn
    }
    render () {
        if (this.props.isLoggedIn) {
            return <UserGreeting  />;
        }
        return <GuestGreeting  />;
    }
}


class SetGreeting extends React.Component {
    constructor() {
        super()
        this.state = {
            isLoggedIn: true
        }
    }
    render () {
        return (
            <div>
                <Greeting isLoggedIn={this.state.isLoggedIn}  />
                <button onClick={() => {
                    this.setState({
                        isLoggedIn: !this.state.isLoggedIn
                    })
                }}>change</button>
            </div>
        )
    }
}

function setGreeting (props) {
    const isLoggedIn = props.isLoggedIn;

}


ReactDOM.render(
    // Try changing to isLoggedIn={true}:
    <SetGreeting  />,
    document.getElementById('root')
);

元素变量

你可以使用变量来存储元素。它可以帮助你有条件地渲染组件的一部分,而其他的渲染部分并不会因此而改变。 观察这两个组件,他们分别代表了注销和登录按钮:

function LoginButton(props) {
  return (
    <button onClick={props.onClick}>
      Login
    </button>
  );
}

function LogoutButton(props) {
  return (
    <button onClick={props.onClick}>
      Logout
    </button>
  );
}

下面我们创建一个名叫LoginControl的有状态组件,它将根据当前的状态来渲染 或者 。同时它还会渲染上一个示例中的

function LoginButton (props) {
    return (
        <button onClick={props.onClick}>
            Login
        </button>
    );
}

function LogoutButton (props) {
    return (
        <button onClick={props.onClick}>
            Logout
        </button>
    );
}

class LoginControl extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            isLoggedIn: true
        }
        this.handleLoginClick = this.handleLoginClick.bind(this)
        this.handleLogoutClick = this.handleLogoutClick.bind(this)
    }
    handleLoginClick () {
        this.setState({ isLoggedIn: true });
    }

    handleLogoutClick () {
        this.setState({ isLoggedIn: false });
    }

    render(){
        const isLoggedIn = this.state.isLoggedIn;
        let button;
        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')
  );

声明一个变量并使用if语句进行条件渲染是不错的方式,但有时你可能会使用更为简洁的语法——————jsx的内联条件渲染方法。

与运算符&&

通过花括号包裹代码,你可以在jsx中嵌入任何表达式。这也包括JavaScript中的逻辑与运算符。他可以很方便地进行元素的条件渲染。

function Mailbox (props) {
    const unreadMessages = props.unreadMessages;
    return (
        <div>
            <h1>hello !</h1>
            {
                unreadMessages.length > 0 &&
                <h2>
                    you have {unreadMessages.length} unreadMessages.
                  </h2>
            }
        </div>
    )
}

const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
    <Mailbox unreadMessages={messages}  />,
    document.getElementById('root')
);

之所以能这样做是因为在JavaScript中,之所以能这样做是因为在 JavaScript 中,true && expression 总是会返回 expression, 而 false && expression 总是会返回 false。 因此,如果条件是true&&右侧元素就会被渲染,如果是false的话,React就会忽略并跳过他。

三目运算符

另一种内联条件渲染的方法是使用JavaScript中的三目运算符。 渲染一段文本:

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>
  );
}

组织组件渲染

在极少数情况下,你可能希望能英寸组件,即使它已经被其他组件渲染。若要完成此操作,你可以让render方法直接返回null,而不进行任何渲染。

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(function(state,props){
            return {
                showWarning:!state.showWarning
            }
        })
    }

    render () {
        return (
            <div>
                <WarningBanner warn={this.state.showWarning}  />
                <button onClick={this.handleToggleClick}>
                    {this.state.showWarning ? 'Hide' : 'Show'}
                </button>
            </div>
        );
    }
}

ReactDOM.render(
    <Page  />,
    document.getElementById('root')
);

在组件的 render 方法中返回 null 并不会影响组件的生命周期。例如,上面这个示例中,componentDidUpdate 依然会被调用。