👨🎓
Почему не стоит использовать build-функции внутри виджетовЧасто встречаю в чужом коде (и нейросети регулярно предлагают) такой паттерн:
Widget build(BuildContext context) {
return Column(
children: [
_buildHeader(),
_buildContent(),
_buildFooter(),
],
);
}На первый взгляд — разумно.
Обычно это объясняют «улучшением читаемости».
Читаемость — вещь субъективная.
Но есть три объективные и практические причины, почему так делать не стоит.
1. Отсутствие архитектурных границ
Правильный подход — выносить UI в отдельные виджеты и, по возможности, держать верстку в ui_kit.
При таком подходе:
- все необходимые данные явно передаются через параметры
- либо виджет сам слушает нужные ему состояния
class Header extends StatelessWidget {
final String title;
final bool isLoading;
const Header({
required this.title,
required this.isLoading,
});
}Это заставляет:
✔️ явно определить зависимости
✔️ зафиксировать контракт
✔️ понимать, кто от кого зависит и что использует
build-функции работают иначе.
Они находятся внутри родительского виджета и:
❗️ имеют доступ ко всем его полям
❗️ могут читать и обновлять переменные стейта
В итоге:
- зависимости неявные
- границы ответственности размыты
- код начинает «протекать» между частями экрана
2. Отсутствие оптимизации
- Flutter эффективно работает за счёт дерева виджетов:
- изолирует rebuild’ы
- оптимизирует обновления
- переиспользует части UI
_buildHeader() — это не виджет, а обычная функция.
И для Flutter нет возможности изолировать пересборку
Любое изменение состояния
→ пересобирается весь build() целиком.
3. Файл начинает расползаться
На старте всё выглядит безобидно:
2–3 build-функции
~100 строк кода
Но со временем:
функции начинают использовать общие данные
появляется условная логика
части экрана начинают менять состояние родителя
Разделить это становится сложно, и каждый раз:
«проще добавить ещё одну функцию, чем делать рефакторинг»
В итоге - количество функций и длина файла растут вместе с проектом.
В нашей практике были виджеты до 3000 строк в одном файле, даже подумать о рефакторинге которого страшно.
Это не теория.
Это типичное состояние проектов, которые приходят к нам на поддержку.
И рефакторинг таких экранов — всегда болезненный.
Рекомендации команды DartWay
1. Не использовать build-функции и приватные UI-виджеты в том же файле
Они создают иллюзию структуры без реальных границ.
2. Дробить UI на отдельные виджеты
Каждый логический кусок интерфейса — отдельный класс с явными входными параметрами.
3. Максимально выносить UI в ui_kit