I am using Bloc for my application, however I was doing something wrong and that is, providing all BlocProvider creates in the MaterialApp
and I would not like to follow that bad practice.
Let's suppose that when I navigate to ScreenA, we create the Bloc as follows :
case PageNames.screenA:
return PageTransition( // Some class that navigates
duration: const Duration(milliseconds: 400),
child: BlocProvider<ScreenABloc>(
create: (context) => ScreenABloc(),
child: const ScreenAPage(),
),
);
Now inside ScreenA, I will do a navigation to ScreenB, and everything is fine, however inside ScreenB at the bottom of my widget tree I want to access the ScreenABloc again, but I can't assign a BlocProvider.value
because I get :
ProviderNotFoundException (Error: Could not find the correct Provider<ScreenABloc> above this Welcome Widget
return BlocProvider.value(
value: BlocProvider.of<ScreenABloc>(context),
child: child ...
);
So I am not sure how to get the supplier that has already been created, or if I should re-create it or what to do in those cases.
CodePudding user response:
You can create a method of creating BlocProvider
in the screen itself, then you can use that method for navigating and creating providers for you.
Here's an example:
class MyWidget extends StatelessWidget {
const MyWidget({super.key});
static Widget create() {
return MultiBlocProvider(
providers: [
BlocProvider<SignInBloc>(
create: (BuildContext context) => SignInBloc(),
),
],
child: const SignInScreen(),
);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
CodePudding user response:
you should use BlocProvider.value
when you push a new route:
/// declare the bloc
final _screenABloc = ScreenABloc();
then use it in both ScreenA
and ScreenB
case PageNames.screenA:
return PageTransition( // Some class that navigates
duration: const Duration(milliseconds: 400),
child: BlocProvider.value(
value: _screenABloc,
child: const ScreenAPage(),
),
);
case PageNames.screenB:
return PageTransition( // Some class that navigates
duration: const Duration(milliseconds: 400),
child: BlocProvider.value(
value: _screenABloc,
child: const ScreenBPage(),
),
);
CodePudding user response:
Correction
Using all BlocProviders
in the starting of the file is not considered bad practice.
Why ?
According to official docs
By default,
BlocProvider
will create the bloclazily
, meaning create will get executed when the bloc is looked up via BlocProvider.of(context).
What is the efficient way ?
Use MultiBlocProvider
in the start of your app
and leave the memory problems to BlocProvider
it will take care of initialization
and disposing
as and when required.