CodeBlanks Logo Icon CodeBlanks

BlocListener

BlocListener ile yan etkileri yönetmeyi öğrenirsin.

BlocListener nedir?

BlocListener, Bloc veya Cubit state değiştiğinde yan etki (side effect) çalıştıran bir widget'tır. Snackbar gösterme, sayfa geçişi, dialog açma gibi işler BlocBuilder yerine BlocListener ile yapılır. Her state değişikliğinde listener callback'i bir kez çağrılır.

BlocListener<LoginBloc, LoginState>(
  listener: (context, state) {
    if (state is LoginSuccess) {
      Navigator.pushNamed(context, '/home');
    }
  },
  child: Text('Login'),
)

listenWhen

listenWhen callback'i, listener'ın ne zaman çalışacağını koşullar. Örneğin yalnızca başarı durumunda çalışmasını istersen listenWhen: (previous, current) => current is LoginSuccess yazarsın. Bu, gereksiz yan etkileri önler.

BlocListener<LoginBloc, LoginState>(
  listenWhen: (prev, curr) => curr is LoginSuccess,
  listener: (context, state) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Giriş başarılı')));
  },
  child: Container(),
)

Uygulama State akışını dinle

bloc.stream.listen, BlocListener'ın temelidir. LoginBloc oluştur, String? message tanımla. Stream'i dinle ve LoginSuccess olduğunda message'a 'Welcome ${state.user}' ata. Event'i tetikle, bekle ve message'ı yazdır.

Başlangıç kodu

main.dart
import 'package:bloc/bloc.dart';

abstract class LoginEvent {}
class LoginSubmittedEvent extends LoginEvent {}

abstract class LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {
  final String user;
  LoginSuccess(this.user);
}

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  LoginBloc() : super(LoginLoading()) {
    on<LoginSubmittedEvent>((event, emit) =>
      emit(LoginSuccess('Ayşe')));
  }
}

void main() async {
  final bloc = LoginBloc();
  String? message;
  // stream dinleyici ekle
  // LoginSuccess olduğunda message'a 'Welcome ${state.user}' ata
  bloc.add(LoginSubmittedEvent());
  await Future.delayed(Duration(milliseconds: 10));
  // message'i yazdır
}

Örnek çözüm

main.dart
import 'package:bloc/bloc.dart';

abstract class LoginEvent {}
class LoginSubmittedEvent extends LoginEvent {}

abstract class LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {
  final String user;
  LoginSuccess(this.user);
}

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  LoginBloc() : super(LoginLoading()) {
    on<LoginSubmittedEvent>((event, emit) =>
      emit(LoginSuccess('Ayşe')));
  }
}

void main() async {
  final bloc = LoginBloc();
  String? message;
  bloc.stream.listen((state) {
    if (state is LoginSuccess) {
      message = 'Welcome ${state.user}';
    }
  });
  bloc.add(LoginSubmittedEvent());
  await Future.delayed(Duration(milliseconds: 10));
  print(message);
}

Beklenen çıktı

Welcome Ayşe

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 BlocListener ne zaman BlocBuilder yerine kullanılır?

  • Bloc'tan veri çekmek için
  • Arayüzü yeniden inşa etmek gerektiğinde
  • State'i sadece okumak için
  • Yan etki (navigation, snackbar) yapmak gerektiğinde Doğru cevap

Açıklama: BlocBuilder arayüzü inşa eder; BlocListener ise yan etki yapar ve widget üretmez.

2 BlocListener parametresi

Soru
BlocListener<LoginBloc, LoginState>(
  ____: (context, state) {
    if (state is LoginSuccess) {
      print('Giriş başarılı');
    }
  },
  child: Container(),
)
Cevap
BlocListener<LoginBloc, LoginState>(
  listener: (context, state) {
    if (state is LoginSuccess) {
      print('Giriş başarılı');
    }
  },
  child: Container(),
)

Açıklama: BlocListener'ın yan etki callback'i listener parametresidir; builder BlocBuilder'da kullanılır.

3 BlocListener parçaları

Kavram Anlamı
BlocListener Yan etki widget'ı
listener State değişince çalışır
listenWhen Çalışma koşulu
child Alt widget

İleri seviye bölümündeki tüm dersler