Provider: какво е, мениджър на състоянието на Flutter приложения

Автор: IT Sectr Публикувано: 2026-02-19 Време за четене: 7 мин

Provider — пакет за управление на състоянието за Flutter, създаден от Rémi Rousselet през 2019 г. като обвивка над InheritedWidget. Provider решава проблема с предаването на данни надолу по дървото от widget-ове без props drilling: всякакъв widget получава достъп до състоянието чрез context.read<T>() или context.watch<T>(). Според pub.dev, Provider е най-популярният мениджър на състоянието на Flutter с повече от 25 хиляди апрекиации.

Основни неща

  • ChangeNotifier — клас с notifyListeners за уведомяване на абонатите за промяна
  • Consumer — widget, който се преизгражда при промяна на ChangeNotifier
  • MultiProvider — композиция от няколко Provider без вложеност
  • ProxyProvider — Provider, който зависи от друг Provider
  • context.read / context.watch — методи за четене на състоянието без и с абонамент

Какво е Provider?

Provider — пакет за управление на състоянието и инжектиране на зависимости в Flutter, построен върху InheritedWidget. Provider предоставя обект (състояние, услуга, репозиториум) в дървото от widget-ове и автоматично преизгражда UI при промяна на данните. За разлика от директното използване на InheritedWidget, Provider премахва цялата boilerplate.

Provider е официално препоръчан от Google за управление на състоянието в Flutter (Flutter Team, 2019-2023). Според Flutter Community Survey 2025, Provider се използва в 72% от Flutter приложенията.

ChangeNotifier и notifyListeners

ChangeNotifier — вграден клас на Flutter, който имплементира модела Listener. ChangeNotifier уведомява абонатите за промяна чрез извикването на notifyListeners().

Dart
class CounterProvider extends ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }

  void reset() {
    _count = 0;
    notifyListeners();
  }
}

Правила на notifyListeners: извиквайте след пълна промяна на данните — не в средата на метода, а в края. При много промяни извиквайте notifyListeners() веднъж след всички промяни.

Consumer и context.watch

Consumer — widget, който се абонира за ChangeNotifier и се преизгражда при всяко извикване на notifyListeners().

Dart
Consumer<CounterProvider>(
  builder: (context, provider, child) => Column(
    children: [
      child!, // не се преизгражда
      Text('${provider.count}'),
      ElevatedButton(
        onPressed: () => provider.increment(),
        child: Icon(Icons.add),
      ),
    ],
  ),
  child: Text('Брояч:'),
)

context.watch — метод за разширение на BuildContext за абониране към Provider. context.read — достъп без абонамент. context.select — абониране за конкретно поле на модела.

MultiProvider и ProxyProvider

MultiProvider — widget за регистриране на няколко Provider без вложеност. ProxyProvider — Provider, който зависи от друг Provider.

Dart
MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => CartProvider()),
    ChangeNotifierProvider(create: (_) => AuthProvider()),
    ProxyProvider<AuthProvider, OrderProvider>(
      update: (_, auth, __) => OrderProvider(auth.userId),
    ),
  ],
  child: MaterialApp(home: HomePage()),
)

Тестване на Provider

Provider се тества чрез увиване на widget-а в MultiProvider с тестови стойности.

Dart
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('Counter increments on button tap',
    (tester) async {
      await tester.pumpWidget(
        ChangeNotifierProvider(
          create: (_) => CounterProvider(),
          child: CounterScreen(),
        ),
      );
      await tester.tap(find.byKey(Key('increment')));
      await tester.pump();
      expect(find.text('1'), findsOneWidget);
    },
  );
}

Provider: производителност и ограничения

Производителността на Provider се базира на InheritedWidget: при промяна на Provider всички абонирани чрез context.watch или Consumer widget-ове се преизграждат. Използвайте context.select, Consumer с параметър child и const за статични widget-ове.

МетодАбонаментПреизгражданеИзползване
context.watchЦял моделВсяка промянаПрости widget-ове
ConsumerЦял моделВсяка промянаС child оптимизация
context.selectКонкретно полеСамо при промяна на полетоСложни модели
context.readНямаНикогаОбработчици на събития

Често задавани въпроси

С какво се различава Provider от BLoC?

Provider — обвивка над InheritedWidget за инжектиране на зависимости с ChangeNotifier. BLoC — архитектурен модел с Event + Stream за изолация на логика.

Какво е ChangeNotifierProvider?

ChangeNotifierProvider — тип Provider за инстанции на ChangeNotifier. Създава обект чрез create, предоставя го на потомъците и преизгражда Consumer при извикване на notifyListeners.

Как да избегна ненужното преизграждане с Provider?

Използвайте context.select вместо context.watch. Разделете големите ChangeNotifier на няколко малки.

Може ли Provider да се използва без ChangeNotifier?

Да. Provider за непроменяеми обекти. StreamProvider за потоци. FutureProvider за Future. ProxyProvider за Provider, които зависят от други.

Какво е ProviderNotFoundException?

ProviderNotFoundException — изключение по време на изпълнение, което възниква при опит за получаване на Provider, който не е деклариран по-горе в дървото от widget-ове.

Обобщение

  • Provider — обвивка над InheritedWidget за управление на състоянието и DI в Flutter
  • ChangeNotifier — клас с notifyListeners за реактивно обновяване на UI
  • Consumer и context.watch — абониране за промяни с автоматично преизграждане
  • MultiProvider — композиция на provider-и без вложеност на дървото
  • ProxyProvider — верига от зависимости между Provider-ите
  • context.select — точен абонамент за конкретно поле на модела
  • StreamProvider и FutureProvider — вградена подкрепа за реактивни и асинхронни данни

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също