flutter_bloc widget-ləri və rebuild sahəsi
flutter_bloc bloc-u UI-a bağlayan bir dəst widget verir. Sənədin vacib qeydi: bu widget-lərin hamısı həm `Cubit`, həm `Bloc` ilə işləyir — ona görə Cubit-dən Bloc-a keçid UI kodunu dəyişmir.
BlocProvider— bloc-u ağaca yerləşdirir və ömrünü idarə edir;MultiBlocProvideryuvalanmanı düzləşdirir.BlocBuilder— state-ə görə UI qurur;buildWhenşərti hansı dəyişikliklərin rebuild doğurduğunu süzgəcdən keçirir.BlocSelector— state-in bir hissəsini seçir; seçilən dəyər dəyişməyibsə rebuild olunmur. Sənədin şərti: seçilən dəyər immutable olmalıdır, əks halda müqayisə düzgün işləmir.BlocListener— rebuild etmədən yan effekt: SnackBar, dialoq, naviqasiya;listenWhenilə süzgəc.BlocConsumer— builder və listener-in birləşməsi.RepositoryProvider— repository/service kimi state saxlamayan obyektlər üçün.
| Ehtiyac | Widget | Qeyd |
|---|---|---|
| State-ə görə UI qurmaq | `BlocBuilder` | Rebuild sahəsi builder-in içi ilə məhdudlaşır |
| Yalnız bir sahəni izləmək | `BlocSelector` | Seçilən dəyər immutable olmalıdır |
| SnackBar, dialoq, naviqasiya | `BlocListener` | Rebuild etmir; `listenWhen` ilə süzgəclənir |
| Hər ikisi birlikdə | `BlocConsumer` | `buildWhen` və `listenWhen` ayrıca verilir |
| Callback-də event əlavə etmək | `context.read<T>()` | `BlocProvider.of<T>(context)` ilə funksional olaraq eynidir; dinləmir |
| Repository/service ötürmək | `RepositoryProvider` | State bildirişi yoxdur — sadəcə DI |
dart
class TodoPage extends StatelessWidget {
const TodoPage({super.key});
@override
Widget build(BuildContext context) {
return BlocListener<TodoBloc, TodoState>(
// Yalnız xəta yeni yarandıqda işləyir.
listenWhen: (previous, current) => previous.error != current.error && current.error != null,
listener: (context, state) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.error!)),
);
},
child: Scaffold(
appBar: AppBar(
// Yalnız sayğac dəyişdikdə bu hissə rebuild olunur.
title: BlocSelector<TodoBloc, TodoState, int>(
selector: (state) => state.todos.length,
builder: (context, count) => Text('Tapşırıqlar ($count)'),
),
),
body: BlocBuilder<TodoBloc, TodoState>(
// Status dəyişməyibsə siyahını yenidən qurmuruq.
buildWhen: (previous, current) =>
previous.status != current.status || previous.todos != current.todos,
builder: (context, state) => switch (state.status) {
TodoStatus.loading => const TodoSkeleton(),
TodoStatus.failure => const ErrorView(),
TodoStatus.success => TodoListView(todos: state.todos),
TodoStatus.initial => const SizedBox.shrink(),
},
),
floatingActionButton: FloatingActionButton(
// read: dinləmir, callback üçün düzgün seçimdir.
onPressed: () => context.read<TodoBloc>().add(TodoAdded('Yeni')),
child: const Icon(Icons.add),
),
),
);
}
}Rebuild sahəsini dəqiq idarə etmək.
Sənədin birbaşa göstərişləri:
- ✅ Callback-lərdə event əlavə etmək üçün
context.readistifadə edin. - ❌
buildmetodunda state oxumaq üçüncontext.readistifadə etməkdən çəkinin — sənədin ifadəsi ilə bu, səhvə meyllidir, çünki state dəyişdikdə widget rebuild olunmayacaq. context.watch<T>()BlocProvider.of<T>(context, listen: true)ilə funksional olaraq eynidir və yalnızStatelessWidget-in ya daStatesinfininbuildmetodunda əlçatandır.- ✅ Rebuild sahəsini açıq şəkildə məhdudlaşdırmaq üçün
context.watchyerinəBlocBuilderistifadə edin (ya daBuilderilə sahəni daraltın).
📚 Mənbələr və sənədlər
- Flutter Bloc konseptlərirəsmibloclibrary.dev
Bütün widget-lərin, buildWhen/listenWhen və context.read/watch/select qaydalarının rəsmi mənbəyi.
- package:flutter_blocrəsmipub.dev
- package:provider (extension-ların mənbəyi)rəsmipub.dev
flutter_bloc context.read/watch/select extension-larını bu paketdən export edir.