Как разработчики React, мы все через это проходили. Устремив пристальный взгляд на свой JSX, пытаемся справиться с проблемой условного рендеринга и испытываем приступ разочарования. Рассмотрим распространенные фрагменты кода.

```jsx
{isVisible && (
  <>
    <Header />
    <Content />
  </>
)}

{
  isLoggedIn 
  ? <UserDashboard /> 
  : <LoginForm />
}

Приведенный выше код работает, но какой ценой? 

  1. Излишние скобки делают его трудночитаемым.
  1. Вложенные условия? С ними все становится по-настоящему запутанным.
  1. Способ обработки условного рендеринга получается не таким элегантным и интуитивно понятным, как хотелось бы.

Конечно, этот код — не шоу-стоппер, в нем нет системных багов. Но он, как камешек в ботинке, вызывает постоянную досаду, которая со временем может измотать вас. 

Источник вдохновения: элегантное решение Solid.js 

Самое время представить Solid.js — фреймворк, который отличается инновационными подходами. Одна из его возможностей особо привлекла мое внимание: более элегантный способ обработки условного рендеринга.

Решение: представляем компонент Show 

Вдохновленные Solid.js, создадим компонент Show, чтобы упростить условный рендеринг:

interface ShowProps<T> {
  when: T | undefined | null | false;
  fallback?: React.ReactNode;
  children: React.ReactNode | ((item: T) => React.ReactNode);
}

function Show({ when, fallback = null, children }) {
  return when ? children : fallback;
}

Применение: до и после 

1. Основы условного рендеринга

До:

{isLoading && <Spinner />}

После:

<Show when={isLoading}>
  <Spinner />
</Show>

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

До:

{isAdmin 
  ? <AdminPanel /> 
  : <UserPanel />
}

После:

<Show 
  when={isAdmin}
  fallback={<UserPanel />}
>
  <AdminPanel />
</Show>

3. Сложный условный рендеринг

До:

{isCommentsEnabled && (
  <>
    <CommentsHeader />
    {comments.map(comment => (
      <CommentItem key={comment.id} {...comment} />
    ))}
    {isLoggedIn && <CommentForm />}
  </>
)}

После:

<Show when={isCommentsEnabled}>
  <CommentsHeader />
  {comments.map(comment => (
    <CommentItem key={comment.id} {...comment} />
  ))}
  <Show when={isLoggedIn}>
    <CommentForm />
  </Show>
</Show>

4. Условный рендеринг с обработкой данных

До:

{user && (
  <div>
    Welcome, {user.name}!
    {user.isAdmin && <AdminBadge />}
  </div>
)}

После:

<Show when={user}>
  {(userData) => (
    <div>
      Welcome, {userData.name}!
      <Show when={userData.isAdmin}>
        <AdminBadge />
      </Show>
    </div>
  )}
</Show>

Двигаемся дальше: поддержка асинхронных данных

Зачем останавливаться на достигнутом? Добавим поддержку асинхронных данных:

const AsyncShow = ({ when, fallback, children }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [data, setData] = useState(null);

  useEffect(() => {
    Promise.resolve(when).then(result => {
      setData(result);
      setIsLoading(false);
    });
  }, [when]);

  if (isLoading) return fallback;
  return data ? children : null;
};

// Использование 
<AsyncShow 
  when={fetchUserData()} 
  fallback={<Loading />}
>
  {user => <UserProfile data={user} />}
</AsyncShow>

Заключение: минимальное улучшение — максимальный эффект 

Этот простой компонент не только делает код чище и читабельнее, но и повышает эффективность разработки. Иногда самые незначительные изменения могут принести наиболее впечатляющие плоды! 

Помните: в грандиозном представлении React-разработки часто именно актеры второго плана, такие как компонент Show, оказывают влияние на ситуацию. Так что, как поется в известной песне, «The Show must go on!» («Шоу должно продолжаться!») и пусть ваш условный рендеринг будет всегда элегантным.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Xiuer Old: Revolutionizing React’s Conditional Rendering

Предыдущая статьяЧистая реализация структуры проекта на Go
Следующая статьяКак создать анимацию кругового вытеснения в Jetpack Compose