Настройка архитектуры Provider для Flutter-приложения
Provider — самый популярный пакет Flutter по числу загрузок. Он обёртывает InheritedWidget в удобный API и избавляет от необходимости вручную прокидывать зависимости через дерево виджетов. Для проектов малого и среднего масштаба Provider — прагматичный выбор: минимум бойлерплейта, максимум читаемости.
Базовая структура с ChangeNotifier
class ProfileNotifier extends ChangeNotifier {
final UserRepository _repository;
ProfileNotifier(this._repository);
UserProfile? _profile;
bool _isLoading = false;
String? _error;
UserProfile? get profile => _profile;
bool get isLoading => _isLoading;
String? get error => _error;
Future<void> load(String userId) async {
_isLoading = true;
_error = null;
notifyListeners();
try {
_profile = await _repository.getProfile(userId);
} catch (e) {
_error = e.toString();
} finally {
_isLoading = false;
notifyListeners();
}
}
}
Регистрация в дереве виджетов:
MultiProvider(
providers: [
RepositoryProvider(create: (_) => UserRepositoryImpl()),
ChangeNotifierProxyProvider<UserRepositoryImpl, ProfileNotifier>(
create: (ctx) => ProfileNotifier(ctx.read()),
update: (ctx, repo, prev) => prev!..updateRepo(repo),
),
],
child: MyApp(),
)
В виджете: context.watch<ProfileNotifier>() для подписки на изменения, context.read<ProfileNotifier>() для вызова методов без подписки.
Главная ловушка Provider
context.watch() внутри build() пересобирает весь виджет при любом notifyListeners(). Если ProfileNotifier вызывает notifyListeners() трижды за одну загрузку — три перерисовки. Решение: Selector<ProfileNotifier, UserProfile?> подписывается только на конкретное поле, перерисовка только при его изменении.
Selector<ProfileNotifier, bool>(
selector: (_, notifier) => notifier.isLoading,
builder: (_, isLoading, __) => isLoading
? const CircularProgressIndicator()
: const SizedBox(),
)
Когда Provider достаточен
Provider подходит: небольшое приложение (до 15–20 экранов), команда 1–2 разработчика, нет сложных зависимостей между экранами. Для приложений с реактивными потоками данных (WebSocket, realtime) или сложной навигацией — рассмотрите Riverpod или BLoC.
Что настраиваем
MultiProvider на уровне MaterialApp. Слоистая структура: repository → notifier → widget. Тестирование через ProviderContainer без Flutter-зависимости. Образцовый экран как шаблон для команды.
Сроки
Настройка Provider-архитектуры: 1–2 дня. Стоимость — после анализа требований.







