I have a bottom nav bar that has a list page that uses a bloc for the state.
class _MainPageState extends State<MainPage> {
int _index = 0;
@override
Widget build(BuildContext context) {
final List<Widget> _widgets = [
const ListPage(),
Scaffold(),
Scaffold(),
];
return Scaffold(
body: IndexedStack(
index: _index,
children: _widgets,
),
bottomNavigationBar: BottomNavigationBar(
...
class ListPage extends StatelessWidget {
const ListPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) =>
getIt<ListBloc>()..add(const ListEvent.load(limit: 10)),
child: SafeArea(
child: Scaffold(
appBar: AppBar(),
body: const List(),
),
),
);
}
}
The problem is build
is beeing called 4 times. This causes the event fetching the list 4 times.
Don't know where to add the event to prevent re-builds.
If I add the event in statefull widget's initState
. Bloc does not recognize ListBloc beeing in the context when fetching the bloc down the widget tree.
The build method is called any time you call setState , your widget's dependencies update, or any of the parent widgets are rebuilt (when setState is called inside of those). Your widget will depend on any InheritedWidget you use, e.g. Theme. of(context) , MediaQuery.
Why FutureBuilder Called again? This is due to state changes that come if setState() called, which triggers build() method, and due to this inside widgets will be re-initialize again.
How to Call Method after Build in Flutter. To call method after build is completed, the idea is to use the addPostFrameCallback callback and add your method inside it. As its name suggests it allows you to register a callback after the last frame of your page is drawn.
The best way is to add event in initState of you main route (Route that contains Bottom Navigation). As shown in below code.
class _MainPageState extends State<MainPage> {
int _index = 0;
@override
void initState() {
super.initState();
getIt<ListBloc>().add(const ListEvent.load(limit: 10));
}
@override
Widget build(BuildContext context) {
final List<Widget> _widgets = [
const ListPage(),
Scaffold(),
Scaffold(),
];
return Scaffold(
body: IndexedStack(
index: _index,
children: _widgets,
),
bottomNavigationBar: BottomNavigationBar(
...
class ListPage extends StatelessWidget {
const ListPage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) =>
getIt<ListBloc>(),
child: SafeArea(
child: Scaffold(
appBar: AppBar(),
body: const List(),
),
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With