Что выберешь: Provider или InheritedWidget?

Ответ

Для большинства задач я выбираю Provider, так как это надстройка над InheritedWidget, которая решает типичные проблемы в пару строк кода.

Provider даёт готовые провайдеры для ChangeNotifier, ValueNotifier, Stream и Future. Он управляет жизненным циклом объектов и оптимизирует перестроения виджетов с помощью context.select. Пример из моего кода:

// Объявление провайдера
ChangeNotifierProvider(
  create: (_) => CartModel(),
  child: const MyApp(),
);

// Использование в виджете
final cart = context.watch<CartModel>(); // Автоматическая подписка
// Или для оптимизации:
final total = context.select((CartModel cart) => cart.totalPrice);

InheritedWidget я использую напрямую только в специфичных случаях, например, для кастомной передачи очень простых данных по дереву или когда нужно максимальное быстродействие без сторонних пакетов. Его реализация требует больше шаблонного кода (объявление класса, статический метод of).

Таким образом, Provider — это стандартный, проверенный инструмент для управления состоянием в средних по сложности Flutter-приложениях, который я применяю постоянно.

Ответ 18+ 🔞

А, ну это же классика, ёпта! Ты знаешь, я как посмотрю на эти споры про управление состоянием, так волнение ебать — все такие умные, а по сути-то всё просто, как три копейки.

Вот смотри, для большинства своих дел я беру Provider. Это как взять обычный InheritedWidget, но накачать его стероидами, чтобы он не просто данные таскал, а ещё и мозги включал. Решает типичные проблемы буквально в пару строк, без этой всей ебени с кучей шаблонного кода. Просто красота, а не инструмент.

Provider тебе сразу в коробке даёт готовые штуки для ChangeNotifier, ValueNotifier, Stream и Future. Сам за жизненным циклом объектов следит, перестроения виджетов оптимизирует через context.select. Ну, то есть не тупо всё приложение перерисовывает, если одна циферка в модели поменялась, а только то, что реально нужно. Умно, блядь. Вот смотри, как это у меня в коде выглядит, просто конфетка:

// Объявляем провайдер — раз, и готово.
ChangeNotifierProvider(
  create: (_) => CartModel(),
  child: const MyApp(),
);

// А в виджете используем — чисто, понятно.
final cart = context.watch<CartModel>(); // Автоматически подписался, красава.
// Или если хочешь по-хитрому, чтобы не дёргаться попусту:
final total = context.select((CartModel cart) => cart.totalPrice); // Только на итоговую цену реагируем.

А вот InheritedWidget голыми руками я трогаю только в особых, ядрёных случаях. Ну, например, когда нужно протащить какую-нибудь простую хуйню вроде темы или локали по всему дереву, и хочется сделать это максимально быстро, без лишних пакетов. Но там же, блядь, пиздец какой шаблонный код писать надо: свой класс объявлять, этот статический метод of городить... Овердохуища писанины получается, честно говоря. Терпения ноль ебать на такое.

Так что, короче, вывод простой: Provider — это наш, родной, проверенный временем инструмент для приложений средней руки. На нём и ездим постоянно. А всякие извращения оставляем для особых случаев, когда реально надо.