I'm using BlocConsumer in 'MyButton' widget which is used in all items in a list. When a user press a button, I want to redirect the user to another page based on which button the user clicked (in the below code, a button text is printed instead).
If I run this code, one click on a button prints all texts ("Press 1", "Press 2", "Press 3"). Is it because the exact same listener attached to MyButton widget 3 times and all the listeners are called whenever any of the buttons is clicked? Does it mean that there should not be more than one widget for a bloc on the same page?
I can fix the code by moving BlocConsumer to wrap the Column instead of MyButton. Is this the right way to handle this issue? If that's the case, I have to wrap a larger widget in more complex situation. For example, if the same bloc is used for widgets in appbar and body, then I'll have to wrap the entire page with BlocConsumer.
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() async {
runApp(BlocProvider<MyBloc>(
create: (BuildContext context) => MyBloc(),
child: MaterialApp(
home: Column(
children: [
MyButton(text: "Press 1"),
MyButton(text: "Press 2"),
MyButton(text: "Press 3"),
],
),
),
));
}
class MyButton extends StatelessWidget {
const MyButton({Key? key, required this.text}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return BlocConsumer<MyBloc, MyState>(
listenWhen: (previous, current) {
return true;
},
listener: (context, state) {
print(text);
},
builder: (context, state) {
return TextButton(
key: UniqueKey(),
child: Text(text),
onPressed: () {
context.read<MyBloc>().add(MyEvent());
},
);
},
);
}
}
class MyEvent {}
class MyState {}
class MyBloc extends Bloc<MyEvent, MyState> {
MyBloc() : super(MyState());
@override
Stream<MyState> mapEventToState(MyEvent event) async* {
yield MyState();
}
}