Условный рендеринг в React

В React можно создавать различные компоненты, чтобы инкапсулировать различные варианты поведения, которые вам нужны. Затем, в зависимости от изменений состояния приложения, вы можете рендерить только некоторые из них.

Условный рендеринг в React работает так же, как в JavaScript. Используйте операторы JavaScript, такие как if или условный оператор, чтобы создавать элементы, представляющие текущее состояние, а затем позвольте React обновлять UI на их основе.

Сначала давайте посмотрим на два компонента:

function UserGreeting(props) {
  return <h1>欢迎回来!</h1>;
}

function GuestGreeting(props) {
  return <h1>请先注册。</h1>;
}

Мы создадим компонент Greeting, который отображает один из них в зависимости от того, вошёл ли пользователь в систему:

Пример React

function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />; } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( //Попробуйте изменить isLoggedIn={true}: <Greeting isLoggedIn={false} /> );

Попробуйте »

Переменные элементов

Вы можете использовать переменные для хранения элементов. Это поможет условно рендерить часть компонента, при этом остальная часть вывода не меняется.

В следующем примере мы создадим компонент с состоянием под названием LoginControl.

Он будет рендериться в зависимости от текущего состояния<LoginButton />или<LogoutButton />, а также он отрендерит ... из предыдущего примера.<Greeting />。

Пример React

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> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <LoginControl /> );

Попробуйте »

Оператор AND &&

Вы можете встроить любое выражение в JSX, обернув его в фигурные скобки, включая логический оператор AND && из JavaScript, который позволяет удобно условно отрендерить элемент.

Пример React

function Mailbox(props) { const unreadMessages = props.unreadMessages; return ( <div> <h1>Привет!</h1> {unreadMessages.length > 0 && <h2> У вас есть{unreadMessages.length}непрочитанных сообщений. </h2> } </div> ); } const messages = ['React', 'Re: React', 'Re:Re: React']; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <Mailbox unreadMessages={messages} /> );

Попробуйте »

В JavaScript,true && expressionвсегда возвращаетexpression, в то время какfalse && expression всегда возвращаетfalse。

Следовательно, если условие равноtrue,&&, элемент справа будет отрендерен; если оно равноfalse, React проигнорирует и пропустит его.


Тернарный оператор

Другой метод условного рендеринга — использовать условный оператор 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>
  );
}

Предотвращение рендеринга компонента

В редких случаях может потребоваться скрыть компонент, даже если он отображается другим компонентом. Это можно сделать, заставив метод render возвращать null вместо результата рендеринга.

В следующем примере,<WarningBanner />компонент рендерится условно в зависимости от значения пропа warn. Если значение warn равно false, компонент не будет рендериться:

Пример React

function WarningBanner(props) { if (!props.warn) { return null; } return ( <div className="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.showWarning} /> <button onClick={this.handleToggleClick}> {this.state.showWarning ? 'Hide' : 'Show'} </button> </div> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <Page /> );

Попробуйте »

Возврат null из метода render компонента не влияет на обратные вызовы методов жизненного цикла компонента. Например, componentWillUpdate и componentDidUpdate всё ещё могут быть вызваны.

Другие расширения