Главная / Статьи / Условная обработка в React и отрисовка списков без сложных решений

Условная обработка в React и отрисовка списков без сложных решений

Явные ветки, стабильные ключи списка и шаблоны, которые сохраняют читаемость условной логики интерфейса, когда компоненты в производственных React-приложениях становятся сложнее простых примеров.

1963 слов

В этом руководстве воссоздаётся рабочий подход к условной отрисовке в React и отрисовке списков, а также к пониманию истинной природы свойства key. Акцент делается на контрактах, проверках и коде, который можно просто добавить в репозиторий без необходимости угадывать его назначение. Для обзора определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не пытаясь угадать скрытое состояние. Записывайте время выполнения и затраты рядом с функциональными результатами. Раннее видимость данных предотвращает неожиданные счёты в общих средах.

Условная отрисовка — показывать или не показывать

Для условной отрисовки — чтобы определить, показывать элемент или нет, необходимо заранее задать входные данные, ответственного за выполнение шага и критерии завершения, прежде чем изменять код. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, которое операторы могут проверять. Размещайте типы рядом с компонентами и ограничивайте количество свойств. Чрезмерное количество свойств приводит к проблемам, которых должен был предотвратить TypeScript.

Подход 1 — Разветвление с использованием if, и возврат null при отсутствии отрисовки

Для подхода 1 — ветвление с использованием if, при этом возвращается null, когда ничего не рисуется. Перед изменением кода необходимо определить входные данные, ответственного за шаг и критерии завершения. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо задокументировать как успешный, так и восстановительный пути выполнения. Повторные попытки и обработка некорректных сообщений являются частью продукта. Размещайте типы рядом с компонентами и ограничивайте количество свойств. Чрезмерное количество свойств приводит к проблемам, которых TypeScript предназначен избегать.

type Props = { isInStock: boolean };

function StockBadge({ isInStock }: Props) {
  if (!isInStock) {
    return null; // out of stock — draw nothing
  }
  return <span className="badge">In stock</span>;
}

Подход 2 — один из двух вариантов с использованием тернарного оператора

Для подхода 2 — одного из двух с использованием тернарного оператора — необходимо определить входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочтительнее использовать небольшие, тестируемые единицы вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину. Размещайте типы рядом с компонентами и ограничивайте количество свойств. Чрезмерное количество свойств приводит к проблемам, которых должен был избежать TypeScript. Для подхода 2 — одного из двух с использованием тернарного оператора — необходимо определить входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и затраты рядом с функциональными результатами. Раннее отображение информации предотвращает неожиданные расходы в совместных средах.

function StockBadge({ isInStock }: Props) {
  return (
    <span className="badge">
      {isInStock ? 'In stock' : 'Out of stock'}
    </span>
  );
}

Подход 3 — «Только тогда», когда используется &&

При применении подхода 3 — «Только тогда», когда используется && — необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Конфигурацию следует хранить отдельно от кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, доступном для аудита операторами. Лучше использовать явную условную отрисовку, чем умные сокращения, скрывающие ошибки в производственной среде.

function Cart({ count }: { count: number }) {
  return (
    <div>
      <h2>Cart</h2>
      {count > 0 && <p>Items in cart: {count}</p>}
    </div>
  );
}

Самая распространённая ловушка с && — число 0

Чтобы избежать наиболее распространённой ловушки с && — числом 0, необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо одновременно задокументировать успешный сценарий работы и сценарий восстановления. Повторные попытки и обработка некорректных сообщений являются частью продукта. Лучше использовать явную условную отрисовку, чем умные сокращения, скрывающие ошибки в производственной среде.

function Cart({ count }: { count: number }) {
  return (
    <div>
      <h2>Cart</h2>
      {/* 🔴 trap: if count is 0, "0" shows up on screen */}
      {count && <p>Items in cart: {count}</p>}
    </div>
  );
}

function App() {
  return (
    <>
      <Cart count={0} />
      <Cart count={10} />
    </>
  );
}

export default App;
// ✅ count > 0 is true/false, so it's safe
{count > 0 && <p>Items in cart: {count}</p>}

Отрисовка списка — построение массива в цикле

Для отрисовки списков — построения массива в цикле — определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину. Лучше использовать явное условное отображение, чем умные сокращения, скрывающие ошибки в продакшене. Для отрисовки списков — построения массива в цикле — определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и затраты рядом с функциональными результатами. Раннее видимость проблем предотвращает неожиданные счета в общих средах.

type Product = {
  id: number;
  name: string;
  price: number;
};

const products: Product[] = [
  { id: 1, name: 'Mechanical Keyboard', price: 89000 },
  { id: 2, name: 'Wireless Mouse', price: 45000 },
  { id: 3, name: 'USB Hub', price: 23000 },
];

function ProductList() {
  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>
          {product.name} — {product.price.toLocaleString()} won
        </li>
      ))}
    </ul>
  );
}

key — тег с именем, который React использует для различения элементов

Для ключей — тегов имен, которые React использует для различения элементов, необходимо определить параметры ввода, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Конфигурацию следует хранить вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, доступном для аудита операторами. Списки ключей должны содержать стабильные бизнес-идентификаторы, а не индексы массивов, когда порядок может меняться.

Warning: Each child in a list should have a unique "key" prop.

Ключи должны быть «стабильными и уникальными»

Чтобы ключи были «стабильными и уникальными», необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Необходимо задокументировать как успешный, так и восстановительный сценарии работы. Повторные попытки и обработка некорректных сообщений являются частью продукта. Списки ключей должны содержать стабильные бизнес-идентификаторы, а не индексы массивов, особенно когда порядок элементов может меняться.

<li key={product.id}>   // ✅ each product's unique id — stable

Ловушка — не использовать индексы массива в качестве ключей

Для Trap: не используйте индексы массива в качестве ключей. Определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага причина должна быть однозначно определена. Списки ключей должны представлять собой стабильные бизнес-идентификаторы, а не индексы массива, особенно когда порядок элементов может меняться. Для Trap: не используйте индексы массива в качестве ключей. Определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и затраты рядом с функциональными результатами. Раннее отображение информации предотвращает неожиданные счета в общих средах.

// 🔴 common but dangerous pattern
{products.map((product, index) => (
  <li key={index}>{product.name}</li>
))}

Совмещение элементов — условия + списки

Чтобы всё собрать вместе — условия и списки: определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, доступном для аудита операторами. Размещайте типы рядом с компонентами и ограничивайте количество свойств. Большое количество свойств приводит к проблемам, которых должен был избежать TypeScript.

type Product = {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
};

function ProductList({ products }: { products: Product[] }) {
  // when the list is empty — conditional rendering
  if (products.length === 0) {
    return <p>No products to display.</p>;
  }

  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>
          {product.name} — {product.price.toLocaleString()} won
          {/* badge only when out of stock — && (safe since the left side is boolean) */}
          {!product.inStock && <span className="badge"> (Out of stock)</span>}
        </li>
      ))}
    </ul>
  );
}

// dummy data — swap in an empty array [] to see the "No products" message
const products: Product[] = [
  { id: 1, name: 'Mechanical Keyboard', price: 89000, inStock: true },
  { id: 2, name: 'Wireless Mouse', price: 42000, inStock: false },
  { id: 3, name: 'USB-C Hub', price: 35000, inStock: true },
];

function App() {
  return <ProductList products={products} />;
}

Заключение

В заключение определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Документируйте как успешный, так и восстановительный пути выполнения. Повторные попытки и обработка некорректных сообщений являются частью продукта. Размещайте типы рядом с компонентами и ограничивайте количество свойств. Чрезмерное количество свойств приводит к проблемам, которых TypeScript предназначен избегать.

Ссылки

Для справки: определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. При сбое шага он должен указывать на конкретную причину. Размещайте типы рядом с компонентами и ограничивайте количество передаваемых параметров. Чрезмерное количество параметров приводит к проблемам, которых должен предотвращать TypeScript. Для справки: определите входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Записывайте время выполнения и затраты рядом с функциональными результатами. Раннее отслеживание помогает избежать неожиданных расходов в совместных средах.

Чек-лист операций

Для операционного чек-листа необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность повторно выполнить шаг, исходя из известной точки контроля, без необходимости угадывать скрытое состояние.

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

Предпочитайте явную условную обработку данных вместо умных схем прерывания выполнения, которые скрывают ошибки в производственной среде.

Даёте приоритет надёжности перед красивыми одноразовыми демонстрациями.

Записывайте время выполнения и затраты рядом с функциональными результатами. Ранняя видимость данных предотвращает неожиданные счёты в общих средах.

Предпочитайте явную условную обработку данных вместо умных схем прерывания выполнения, которые скрывают ошибки в производственной среде.

Перед внедрением стека необходимо заморозить версии, сделать копию «золотого» варианта кода для критической части работы и уточнить шаги возврата к предыдущему состоянию. В совместных средах требуются ограничения на скорость работы, проверки принадлежности ресурсов и четко определенный ответственный за обновление секретов.