routemaster
routemaster copied to clipboard
Incorrect interaction with the bloc
hi! I noticed that when using the routemaster, the state change event is triggered twice. With the same code, a regular router works as expected. I created a small project to test the behavior.
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^7.2.0
routemaster: ^0.9.5
import 'package:flutter/scheduler.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:routemaster/routemaster.dart';
Future<void> main() async {
runApp(TestApp());
}
const isNative = false;
class TestApp extends StatelessWidget {
final routes = RouteMap(routes: {
'/': (_) => MaterialPage(child: HomePage()),
'/test': (_) => MaterialPage(child: TestPage()),
});
@override
Widget build(BuildContext context) {
return isNative
? MaterialApp(home: HomePage())
: MaterialApp.router(
routeInformationParser: const RoutemasterParser(),
routerDelegate: RoutemasterDelegate(
routesBuilder: (_) => routes,
),
);
}
}
// Pages
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('page 1'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (isNative) {
Route route = MaterialPageRoute(builder: (context) => TestPage());
Navigator.push(context, route);
} else {
Routemaster.of(context).push('/test');
}
},
),
body: const Text('page 1'),
);
}
}
class TestPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider<TestCubit>(
create: (_) => TestCubit(),
child: BlocBuilder<TestCubit, TestState>(builder: (context, state) {
print(state); // <= 'SecondState' printed twice!!!
if (state is SecondState) {
if (isNative) {
SchedulerBinding.instance!.addPostFrameCallback((_) {
Navigator.pop(context);
});
} else {
Routemaster.of(context).pop();
}
}
return Scaffold(
appBar: AppBar(
title: const Text('page 2'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<TestCubit>().call();
},
),
body: const Text('page 2'),
);
}),
);
}
}
// States
abstract class TestState {}
class InitState extends TestState {}
class SecondState extends TestState {}
//Cubit
class TestCubit extends Cubit<TestState> {
TestCubit() : super(InitState());
Future<void> call() async {
emit(SecondState());
}
}
Hello
i think it's the bloc behavior, it think the BlocBuilder will rebuild if the state is different from the previous one
You can add in your bloc build in order to prevent twice build :
buildWhen(state1, state2) => state1 != state2
, //or something similar
And in the cubit, you can try to emit a const
Future<void> call() async {
emit(const SecondState());
}
Thanks for the answer, I'll try