Sparround

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; MultiBlocProvider yuvalanmanı 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; listenWhen ilə süzgəc.
  • BlocConsumer — builder və listener-in birləşməsi.
  • RepositoryProvider — repository/service kimi state saxlamayan obyektlər üçün.
EhtiyacWidgetQeyd
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.read istifadə edin.
  • build metodunda state oxumaq üçün context.read istifadə 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ız StatelessWidget-in ya da State sinfinin build metodunda əlçatandır.
  • ✅ Rebuild sahəsini açıq şəkildə məhdudlaşdırmaq üçün context.watch yerinə BlocBuilder istifadə edin (ya da Builder ilə sahəni daraltın).

📚 Mənbələr və sənədlər