В React вы можете создавать отдельные компоненты, которые инкапсулируют поведение, которое вам нужно. Затем вы можете отображать только некоторые из них, в зависимости от состояния вашего приложения.
Условный рендеринг в React работает так же, как условные функции в JavaScript. JavaScript-операторы, например if или условный (тернарный) оператор, для создания элементов, представляющих текущее состояние, и React обновит пользовательский интерфейс. Рассмотрим эти два компонента:
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'));Этот пример отображает другое приветствие в зависимости от значения isLoggedIn prop
Переменные элемента
Вы можете использовать переменные для хранения элементов. Это может помочь вам отобразить часть компонента, в то время как остальная часть вывода не изменится. Рассмотрим эти два новых компонента, представляющих кнопки Logout и Login:
function LoginButton(props) { return ( <button onClick={props.onClick}> Login </button> );}
function LogoutButton(props) { return ( <button onClick={props.onClick}> Logout </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 = 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'));Хотя объявление переменной и использование оператора if - прекрасный способ отобразить компонент, иногда вам может понадобиться использовать более короткий синтаксис. В JSX существует несколько способов включения условий, описанных ниже.
Строковый IF и логический оператор AND (&&)
Вы можете вставлять любые выражения в JSX, обертывая их фигурными скобками. Это включает в себя логический && оператор JavaScript. Это может быть удобно для включения элемента:
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 messages = ['React', 'Re: React', 'Re:Re: React'];ReactDOM.render( <Mailbox unreadMessages={messages} />, document.getElementById('root'));Это работает, потому что в 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 вместо вывода рендеринга. В приведенном ниже примере
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.showWarning} /> <button onClick={this.handleToggleClick}> {this.state.showWarning ? 'Hide' : 'Show'} </button> </div> ); }}
ReactDOM.render( <Page />, document.getElementById('root'));Возврат null из метода рендеринга компонента не влияет на запуск методов жизненного цикла компонента. Например, componentWillUpdate и componentDidUpdate все равно будут вызываться.