В React вы можете создавать отдельные компоненты, которые инкапсулируют нужное вам поведение. Затем вы можете отрисовать только некоторые из них, в зависимости от состояния вашего приложения.
Условная отрисовка в React работает так же, как условия работы в JavaScript. Используйте JavaScript-операторы, например if или тернарный оператор, чтобы создать элементы, представляющие текущее состояние, и пусть React обновит пользовательский интерфейс для соответствия им.
Рассмотрим эти два компонента:
function UserGreeting(props) { return <h1>С возвращением!</h1>; } function GuestGreeting(props) { return <h1>Пожалуйста, зарегистрируйтесь.</h1>; }
Мы создадим компонент Greeting, который отрисовывает любой из этих компонентов в зависимости от того, вошел ли пользователь в систему:
function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return ; } return ; } ReactDOM.render( // Попробуйте изменить на isLoggedIn={true}: , document.getElementById('root') );
Этот пример отрисовывает другое приветствие в зависимости от значения свойства isLoggedIn.
Переменные элементы
Вы можете использовать переменные для хранения элементов. Это может помочь вам по условию отрисовать часть компонента, в то время как остальная часть вывода не изменится.
Рассмотрим эти два новых компонента, представляющих кнопки для выхода и авторизации:
function LoginButton(props) { return ( < onClick={props.onClick}> Авторизация </button> ); } function LogoutButton(props) { return ( < onClick={props.onClick}> Выход </button> ); }
В приведённом ниже примере мы создадим компонент с состоянием с именем LoginControl.
Он будет отрисовывать либо или в зависимости от текущего состояния. Он также отрисует из предыдущего примера:
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; if (isLoggedIn) { button = <LogoutButton onClick={this.handleLogoutClick} />; } else { button = <LoginButton onClick={this.handleLoginClick} />; } return ( <div> < isLoggedIn={isLoggedIn} /> {button} </div> ); } } ReactDOM.render( <LoginControl />, document.getElementById('root') );
Хотя объявление переменной и использование оператора if — прекрасный способ по условию отрисовать компонент, иногда возможно вы захотите использовать более короткий синтаксис. В JSX существует несколько способов встроенных условий, описанных ниже.
Встроенный оператор if с логическим оператором &&
Вы можете вставлять любые выражения в JSX, обертывая их фигурными фигурными скобками. Это включает в себя логический JavaScript-оператор &&. Это может быть удобно для условного включения элемента:
Вы можете вставлять любые выражения в JSX, обёртывания их фигурными скобками. Это включает логический JavaScript-оператор &&. Это может быть удобно для условной отрисовки элемента:
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']; ReactDOM.render( <Mailbox unreadMessages={messages} />, document.getElementById('root') );
Это работает, потому что в JavaScript true && expression
всегда вычисляется в expression
, а false && expression
всегда вычисляется в false
.
Поэтому, если условие равно true, элемент справа после && появится в выводе. Если оно false, React игнорирует и пропускает его.
Встроенный оператор if-else с тернарным оператором
Другой метод встроенной условной отрисовки элементов — использование условного оператора в JavaScript условие ? true : false
.
В приведённом ниже примере мы используем его для условной отрисовки небольшого блока текста.
render() { const isLoggedIn = this.state.isLoggedIn; return ( <div> Пользователь <b>{isLoggedIn ? 'в данный момент' : 'не'}</> авторизован. </div> ); }/pre> Он также может использоваться для больших выражений, хотя из-за этого менее очевидно, что происходит:
render() { const isLoggedIn = this.state.isLoggedIn; return ( <div> {isLoggedIn ? ( <LogoutButton onClick={this.handleLogoutClick} /> ) : ( <LoginButton onClick={this.handleLoginClick} /> )} </div> ); }
Как и в JavaScript, вы можете выбрать подходящий стиль, основанный на том, что вы и ваша команда считаете более читабельным. Также помните, что всякий раз, когда условия становятся слишком сложными, возможно, самое время извлечь компонент.
Предотвращение отрисовки компонента
В редких случаях, возможно, вам потребуется скрыть компонент, даже если он был отрисован другим компонентом. Для этого возвращаем null вместо вывода отрисовки.
В приведённом ниже примере отрисовывается в зависимости от значения свойства с названием warn. Если значение этого свойства равно false, то компонент не отрисовывается:
function WarningBanner(props) { if (!props.warn) { return null; } return ( <div className="warning"> Предупреждение! </div> ); } class Page extends React.Component { constructor(props) { super(props); this.= {showWarning: true}; this.handleToggleClick = this.handleToggleClick.bind(this); } handleToggleClick(){ this.setState(state => ({ showWarning: !state.showWarning })); } render(){ return( <div> <WarningBanner warn={this.state.showWarning} /> <button onClick={this.handleToggleClick}> {this.state.showWarning ? 'Скрыть' : 'Показать'} </button> </div> ); } } ReactDOM.render( <Page />, document.getElementById('root') );
Возврат null из метода компонента render не влияет на запуск методов жизненного цикла компонента. Например, componentDidUpdate по-прежнему будет вызываться.