Как ты относишься к созданию виджетов через методы (build-методы) внутри класса?

«Как ты относишься к созданию виджетов через методы (build-методы) внутри класса?» — вопрос из категории UI и вёрстка, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я считаю это антипаттерном, который может привести к проблемам с производительностью и отладкой. Flutter оптимизирует перерисовку через сравнение виджетов по их типу (runtimeType) и ключам (key).

Проблема с методами:

// ❌ Антипаттерн
Widget _buildHeader() {
  return Container(
    padding: EdgeInsets.all(16),
    child: Text('Заголовок'),
  );
}

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      _buildHeader(), // Каждый раз создаётся новый экземпляр Container
      // ...
    ],
  );
}

Flutter не может эффективно кэшировать или сравнивать результат _buildHeader(), так как это просто метод, возвращающий новый виджет. Это приводит к лишним перестроениям.

Правильное решение — выделение в отдельный StatelessWidget:

// ✅ Правильный подход
class Header extends StatelessWidget {
  const Header({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      child: const Text('Заголовок'),
    );
  }
}

// Использование
@override
Widget build(BuildContext context) {
  return Column(
    children: const [
      Header(), // Flutter может эффективно реюзать этот виджет
      // ...
    ],
  );
}

Преимущества подхода с отдельными виджетами:

  • Горячая перезагрузка (Hot Reload) работает корректно.
  • Производительность: Flutter может пропускать перерисовку неизменных виджетов.
  • Отладка: В DevTools и логах видны понятные имена виджетов.
  • Переиспользование: Виджет можно легко использовать в разных частях приложения.

Исключением могут быть очень простые, чисто синтаксические группировки виджетов внутри одного build-метода, но даже тогда я предпочитаю использовать const-конструкторы для встроенных виджетов.