Умовний рендеринг
These docs are old and won’t be updated. Go to react.dev for the new React docs.
These new documentation pages teach modern React and include live examples:
React дозволяє розподілити логіку на окремі компоненти. Ці компоненти можна показувати або ховати в залежності від поточного стану додатку.
Умовний рендеринг у React працює так само, як і умовні вирази працюють в JavaScript. Іноді потрібно пояснити React, як стан впливає на те, які компоненти треба сховати, а які — відрендерити, та як саме. Для цього використовуйте умовний оператор JavaScript, або вирази подібні до if
.
Розглянемо два компоненти:
function UserGreeting(props) {
return <h1>З поверненням!</h1>;
}
function GuestGreeting(props) {
return <h1>Зареєструйтеся, будь-ласка.</h1>;
}
Ми створимо компонент Greeting
, який відображає один з цих компонентів у залежності від того, чи користувач ввійшов до сайту:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) { return <UserGreeting />; } return <GuestGreeting />;}
const root = ReactDOM.createRoot(document.getElementById('root'));
// Спробуйте замінити значення isLoggedIn на true та подивіться на ефект.
root.render(<Greeting isLoggedIn={false} />);
У цьому прикладі різне вітання відрендериться в залежності від значення пропсу isLoggedIn
.
Змінні-елементи
Ви можете використовувати змінні для того, щоб зберігати елементи React. Це допоможе вам умовно рендерити лише частину компонента, в той час, як інша частина компонента залишається незмінною.
Розглянемо ще два компоненти, що представляють кнопки Увійти(Login) та Вийти (Logout)
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Увійти
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Вийти
</button>
);
}
У наступному прикладі ми створимо компонент зі станом під назвою LoginControl
.
Він відрендерить <LoginButton />
, або <LogoutButton />
в залежності від поточного стану. Він також відрендерить <Greeting />
з минулого прикладу:
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>
<Greeting isLoggedIn={isLoggedIn} /> {button} </div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<LoginControl />);
Незважаючи на те, що оголошення змінної та використання if
-виразів для умовного рендерингу є гарним варіантом, але іноді хочеться коротший синтаксис. Для цього існують декілька інших способів для написання умов прямо в JSX, які ми розглянемо нижче.
Вбудовані умови if з логічним оператором &&
Ви можете вставляти будь-який вираз у 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'];
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Mailbox unreadMessages={messages} />);
Цей приклад працює коректно, тому що в JavaScript вираз true && expression
завжди обчислюється як expression
, а вираз false && expression
— як false
.
Отже, якщо умова правдива (true
), то елемент, який йде безпосередньо після &&
, з’явиться у виводі. Якщо ж умова помилкова (false
), React проігнорує та пропустить його.
Note that returning a falsy expression will still cause the element after &&
to be skipped but will return the falsy expression. In the example below, <div>0</div>
will be returned by the render method.
render() {
const count = 0; return (
<div>
{count && <h1>Messages: {count}</h1>} </div>
);
}
Вбудовані умови if-else з тернарним оператором
Іншим методом для умовного рендерингу елементів є використання тернарного оператора condition ? true : false
.
У наступному прикладі ми використаємо цей метод для того, щоб відрендерити маленький шматочок тексту.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
Користувач <b>{isLoggedIn ? 'зараз' : 'не'}</b> на сайті. </div>
);
}
Цей метод також можна використувати для більших виразів, але це може зробити код менш очевидним:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} /> }
</div> );
}
Як у JavaScript, так і в React вибір синтаксису залежить від ваших уподобань і прийнятого у вашій команді стилю. Також пам’ятайте, що якщо якась умова стає занадто складною, можливо прийшов час вилучити частину коду в окремий компонент.
Запобігання рендерингу компонента
Зрідка може виникнути потреба в тому, щоб дозволити компоненту сховати себе, навіть якщо він вже був відрендереним іншим компонентом. Для цього поверніть null
замість того, що зазвичай йде на рендеринг.
У наступному прикладі, <WarningBanner />
буде відрендерено в залежності від значення пропу 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.state = {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>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Page />);
Повернення null
із методу render
ніяк не впливає на спрацювання методів життєвого циклу компонента. Наприклад, componentDidUpdate
все одно буде викликаний.