До какого размера стоит делать React компоненты
Что проверяют
Есть ли у вас критерии, по которым вы решаете разбить компонент, или только правило «не больше N строк». Следом обычно спрашивают, как разбиение влияет на ререндеры и бывают ли компоненты слишком мелкими.
Как отвечать
Честный ответ: универсального лимита в строках нет. Есть сигналы, что компонент пора делить:
- несколько обязанностей: его трудно назвать без союза «и», например «фильтры, таблица и модалка редактирования»;
- много независимого состояния: пачка
useStateиuseEffect, не связанных друг с другом. Связанную логику выносят в свой хукuseXxx, разметка при этом может остаться на месте; - повторение: одинаковый кусок разметки в двух местах;
- разная частота изменений: поле ввода обновляется на каждое нажатие, а тяжёлый список рядом перерисовывается вместе с ним.
Последний пункт напрямую связан с производительностью. Ререндер начинается с компонента, где изменилось состояние, и идёт вниз по поддереву. Если опустить состояние поиска в маленький SearchInput или передать тяжёлую часть через children, список перестанет рендериться на каждый символ. Это дешевле, чем расставлять React.memo и useMemo повсюду, а в проектах с React Compiler ручная мемоизация нужна редко: компилятор расставляет её сам.
Разделение на контейнеры и презентационные компоненты в чистом виде сейчас почти не применяют: с хуками логику выносят в кастомный хук, а не в компонент-обёртку.
У дробления тоже есть граница. Компонент, который используется в одном месте, принимает десяток пропсов и просто пробрасывает их ниже, хуже большого, но цельного. Ориентир качественный: назначение понятно из имени, а файл читается без прыжков вверх и вниз.
Где спотыкаются
Называют жёсткую цифру вроде «не больше 200 строк» или «не больше 5 пропсов» и не могут объяснить, откуда она взялась.
Объявляют компонент внутри тела другого компонента. На каждом рендере это новый тип, React размонтирует поддерево, и теряются состояние и фокус в инпутах.
Дробят всё до атомов заранее и получают prop drilling через пять уровней вместо одного понятного файла.