Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. JSX и типизированные компоненты
jsx_components

JSX и типизированные компоненты

JSX как выражение, чистые функции-компоненты, свойства, `children`, списки, ключи и безопасная композиция.

Открыть лабораториюv0.2.0Запускается локально из публичного репозитория

JSX и типизированные компоненты

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

#Результат урока

Вы научитесь проектировать небольшие чистые компоненты, типизировать их входные данные, сохранять связь элементов списка с данными и собирать интерфейс композицией.

Понадобятся строгий TypeScript, функции, массивы и неизменяемые преобразования. Итог урока — типизированный каталог с семантической разметкой, устойчивыми ключами и переиспользуемыми областями содержимого.

#1. JSX — выражение, а не строковый HTML

JSX преобразуется в вызовы, создающие элементы React. Фигурные скобки вставляют значение выражения; React DOM экранирует строки, поэтому обычный текст не становится HTML. Тег в нижнем регистре означает DOM-элемент, а имя с заглавной буквы — компонент. Возвращаемое дерево должно иметь один корневой элемент или Fragment.

// src/Greeting.tsx type GreetingProps = { name: string }; export function Greeting({ name }: GreetingProps) { return <p>Здравствуйте, {name}</p>; }

Если name содержит <script>, React отобразит текст. Для интерпретации HTML нужен отдельный опасный API, который рассматривается в теме безопасности.

Проверьте себя. Передайте строку с HTML-символами и проверьте, что она отображается как текст.

Частая ошибка. Склеивать пользовательские данные в HTML-строку и вставлять через DOM API.

#2. Чистая функция-компонент

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

Проверьте себя. Отрендерите компонент дважды с одинаковыми входами и проверьте отсутствие новых записей в внешнем массиве.

Частая ошибка. Отправлять аналитику или изменять кеш непосредственно в теле компонента.

#3. Свойства как публичный контракт

Свойства описывают минимальный вход компонента. Не передавайте большой объект предметной области, если нужны только два поля: это усиливает связанность и мешает переиспользованию. Обработчики называют по намерению (onArchive), а тип события DOM оставляют внутри конечного визуального компонента. Значения по умолчанию задают при деструктуризации.

// src/StatusBadge.tsx type StatusBadgeProps = { label: string; tone?: 'neutral' | 'success' | 'danger'; }; export function StatusBadge({ label, tone = 'neutral' }: StatusBadgeProps) { return <span data-tone={tone}>{label}</span>; }

Объединение строковых литералов ограничивает варианты, а необязательное свойство действительно может отсутствовать. null не добавляется автоматически.

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

Частая ошибка. Принимать user: any и читать произвольные поля глубоко внутри визуального компонента.

#4. Типы дочернего содержимого и именованные области

ReactNode описывает всё отображаемое дочернее содержимое: элементы, строки, числа, null и коллекции. ReactElement уже и нужен, когда требуется именно элемент. Именованные свойства header, actions и children делают структуру компонента явной. Не добавляйте children в тип автоматически, если компонент не принимает содержимое.

// src/Panel.tsx type PanelProps = { title: string; actions?: React.ReactNode; children: React.ReactNode; }; export function Panel({ title, actions, children }: PanelProps) { return <section><header><h2>{title}</h2>{actions}</header>{children}</section>; }

Именованные области позволяют родителю передать поведение и разметку, не превращая Panel в компонент с множеством флагов.

Проверьте себя. Соберите две панели с разными действиями, не меняя реализацию Panel.

Частая ошибка. Добавлять логические свойства showEdit, showDelete, showExport для каждой новой кнопки.

#5. Списки и стабильные ключи

key помогает React сопоставить элемент списка с записью между отрисовками. Ключ должен приходить из данных, оставаться стабильным и быть уникальным среди соседей. Индекс допустим лишь для неизменяемого списка без вставок, удаления и перестановки; иначе локальное состояние и DOM могут переехать к другой записи.

// src/ProductList.tsx export function ProductList({ products }: { products: readonly Product[] }) { return <ul>{products.map(product => <ProductRow key={product.id} product={product} /> )}</ul>; }

key не попадает в ProductRow как обычное свойство. Если идентификатор нужен внутри, передайте id отдельно.

Проверьте себя. Введите текст в строке, переставьте товары и проверьте, что текст остаётся у правильного id.

Частая ошибка. Использовать индекс или Math.random() как key изменяемого списка.

#6. Композиция вместо наследования

React-компоненты расширяют через свойства, дочернее содержимое и специализированные обёртки, а не через классовое наследование. Контейнер отвечает за расположение, компонент сценария — за поведение, а конечный визуальный компонент — за DOM. Чем ниже уровень, тем меньше он должен знать о маршрутах, кеше и авторизации.

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

Частая ошибка. Создать базовую страницу с десятками переопределяемых методов и скрытым жизненным циклом.

#7. ref как свойство в React 19

В React 19 функциональный компонент может получать ref как свойство; в новом коде forwardRef больше не нужен. ref даёт императивный доступ к DOM, но не заменяет обычную передачу данных. Указывайте конкретный тип, например Ref<HTMLInputElement>, а отображаемые значения храните в состоянии.

// src/SearchInput.tsx type SearchInputProps = React.ComponentPropsWithRef<'input'> & { label: string; }; export function SearchInput({ label, ref, ...inputProps }: SearchInputProps) { return <label>{label}<input ref={ref} {...inputProps} /></label>; }

ComponentPropsWithRef сохраняет нативные свойства поля и правильный тип ref. Распространяйте свойства осознанно, чтобы не перезаписать защищённые атрибуты.

Проверьте себя. Сфокусируйте поле после явного пользовательского действия через типизированный ref.

Частая ошибка. Хранить отображаемое значение поля только в ref.current.value и ожидать новой отрисовки.

#8. Типы компонентов без ритуалов

Обычная именованная функция с типизированным параметром свойств обычно даёт лучший вывод типов и понятные обобщения. React.FC допустим, но не обязателен и не делает компонент правильнее. Тип результата чаще стоит оставить выводимым; явный ReactNode нужен, если компонент действительно может вернуть текст или null. Импорты через import type явно отделяют типы от кода времени выполнения.

// src/When.tsx import type { ReactNode } from 'react'; type WhenProps = { condition: boolean; children: ReactNode }; export function When({ condition, children }: WhenProps) { return condition ? children : null; }

Функция может вернуть ReactNode; современная связка React types и TypeScript корректно моделирует такой компонент.

Проверьте себя. Сравните диагностику обобщённого компонента, объявленного обычной функцией и через чрезмерно широкую аннотацию.

Частая ошибка. Добавлять React.FC<any> ко всем компонентам, считая это типобезопасностью.

#Лаборатория

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

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

#Источники для сверки

  • React: Describing the UI
  • React: Passing Props
  • React: Rendering Lists
  • React 19 ref as prop

Устранение неисправностей

Далее: Модель рендеринга React