Урок 05

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

Условный рендеринг — это отображение разметки в зависимости от данных. В React для этого используют обычные JS-конструкции.

if / else

Самый прямолинейный способ:

function Greeting({ isLoggedIn }: { isLoggedIn: boolean }) {
    if (isLoggedIn) {
        return <h1>Привет!</h1>;
    }

    return <h1>Войдите</h1>;
}

Работает, когда весь компонент возвращает одну из двух веток.

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

Для условий внутри JSX:

function Status({ isLoading }: { isLoading: boolean }) {
    return (
        <div>
            {isLoading ? <Spinner /> : <Content />}
        </div>
    );
}

Удобно, когда нужно вернуть один из двух элементов.

Логическое И (&&)

Если нужно отрендерить что-то только при истинном условии и ничего при ложном:

function Notification({ message }: { message?: string }) {
    return (
        <div>
            {message && <p className="notification">{message}</p>}
        </div>
    );
}

Если message пустая строка, 0 или null — ничего не отрендерится.

Логическое ИЛИ (||)

Для значений по умолчанию:

function Title({ text }: { text?: string }) {
    return <h1>{text || 'Без названия'}</h1>;
}

Оператор ??

?? возвращает правую часть только если левая — null или undefined. В отличие от ||, не сработает на 0 и пустую строку:

const count = value ?? 0;

Возврат null

Чтобы ничего не рендерить:

function Warning({ show }: { show: boolean }) {
    if (!show) return null;

    return <p>Внимание!</p>;
}

Переменная с разметкой

Можно сохранить JSX в переменную:

function Header({ user }: { user: User | null }) {
    let content;

    if (user) {
        content = <span>{user.name}</span>;
    } else {
        content = <a href="/login">Войти</a>;
    }

    return <header>{content}</header>;
}

Несколько условий

Для нескольких веток — if / else if / else:

function RoleBadge({ role }: { role: 'admin' | 'moderator' | 'user' }) {
    if (role === 'admin') return <span>Админ</span>;
    if (role === 'moderator') return <span>Модератор</span>;
    return <span>Пользователь</span>;
}

Или через объект-маппинг:

const badges = {
    admin: <span>Админ</span>,
    moderator: <span>Модератор</span>,
    user: <span>Пользователь</span>,
};

<span>{badges[role]}</span>

Не рендери что-то, что не нужно

Не надо оборачивать каждый элемент в условие. Если компонент всегда рендерит разметку — не пиши лишних проверок.

Итоги

  • if/else — для крупных веток
  • Тернарник — для одной из двух опций
  • && — для рендера при истине
  • || и ?? — для значений по умолчанию
  • null — чтобы ничего не рендерить