bloc icon indicating copy to clipboard operation
bloc copied to clipboard

Best Practices to follow while using bloc.

Open ritik-playground opened this issue 5 years ago • 13 comments

The flutter_bloc package already has great documentation and examples to get started easily. But, when it comes to the best practices to be followed when using bloc, there's not much sources out there. By best practices, I mean:

  • One Bloc per feature.
  • Don't mutate your state.
  • Don't define any data in the bloc.

If there was a curated article or a video about the best practices to be followed and the things to avoid when using bloc, it would be very much helpful to everyone using the bloc architecture for their works. It would be cool, if it was also included in the official bloclibrary along with the tutorials in there. In brief, a list of Do's and Don'ts related to flutter_bloc.

ritik-playground avatar Oct 12 '20 07:10 ritik-playground

I second this, this is definitely needed for such a popular and complex(at least when you are a beginner) state management solution. For instance I still define some private internal data in my bloc class. And I still don't know if it is too bad :D

aytunch avatar Nov 04 '20 23:11 aytunch

I third this, I use the same bad practice as @aytunch because is the way a learned and seems easy and doesn't give any error.But still I would love to do it the correct way.

MaldonadoAndres avatar Jan 08 '21 14:01 MaldonadoAndres

Even a bloc per feature is not clear for me, for example now I have OrderBloc where I use in more than one screen(e.g: OrderScreen, OrderDetailsScreen, RefundRequestsScreen(since it is related to order) and so on..).

I also have some protected screens where only authenticated users can open, now I use a way that I am feeling is not the best for example: I have WishlistScreen when user tries to get his wishlists I check sharedPrefrence if he has a token I yield state called WishlistsLoaded else I yield AuthenticateToGetWishlists state from WishlistBloc I would like to see examples and recommendations for these scenarios thanks.

@felangel

Add00w avatar Jan 11 '21 08:01 Add00w

If my app have the feature that gets from the backend posts created by an user and other gets posts liked by an user, both endpoints are paginated so i can implement the infinity scroll feature. Do i need to created two cubits or blocs to manage these features?

nfortiz avatar Mar 10 '21 02:03 nfortiz

What is the best to do when I have EditProductScreen , CreateProductScreen and ProductsScreen should I make Bloc for each screen e.g EditBloc, CreateBloc ...., or just ProductsBloc as I do now and use that bloc in all products related screens?

Add00w avatar Apr 07 '21 08:04 Add00w

@nfortiz sounds like 2 different features and you should have a bloc/cubit per each, especially since I'm sure you won't be displaying those 2 post lists on the same page.

@Add00w those are separate features, so each one should have it's own bloc. At most you could try and condense the create and edit into a single bloc if they resemble a lot, but there are pluses and minuses for this approach too.

As for your wishlist you shouldn't be reading auth related stuff from sharedPrefs rather let the auth bloc dictate whether the user is signed in or not and based on that you can act accordingly. You can either inject the auth bloc into the wishlist bloc or you can pass the current user status when adding the initial wishlist event. Alternatively, you might have the user status available in your UserRepository which you could also inject in your wishlist bloc. Your feature is open to different approaches which are based on the requirements.

x1z7 avatar Apr 07 '21 17:04 x1z7

Hello, every one! Is that right to create several blocs in the beginning of widget tree using multiproviders? For example, i have 10 blocs and i want put them all in one place. Seems to me it is not good idea.

pandora-house avatar Nov 20 '21 19:11 pandora-house

@pandora-house I believe dependency injection in presentation layer is bad practice. I use service locator get_it for registering all dependencies. Blocs and cubits registration / unregistration I extract to injection container methods which I call from initState / dispose of according widget (for blocs holding local state) or AppWidget (for blocs holding global state). I do it this way because I need somewhere close blocs to prevent memory leaks and reset bloc local states. The disadvantage of this approach is creating stateful widgets instead of stateless. If someone knows better approach I would like to listen it.

meowofficial avatar Nov 21 '21 03:11 meowofficial

@meowofficial like alternative to get_it is RepositoryProvider acceptable to use?

pandora-house avatar Nov 23 '21 11:11 pandora-house

@pandora-house I don't know because I didn't use Provider as main dependency injection tool. I know that author of Provider introduced new package riverpod as better alternative.

meowofficial avatar Nov 23 '21 11:11 meowofficial

RepositoryProvider comes with flutter_bloc and u can use to register repositories for your app and blocs/cubits(maybe).

Add00w avatar Nov 30 '21 08:11 Add00w

@Add00w @pandora-house

I think RepositoryProvider at the top is the pattern you want to use. I'm writing the docs for a the flutter_todos tutorial that uses Repository provider with 3 common cubits. I made a diagram of the widget tree in that tutorial, and this touches on where to put providers. See this post: https://github.com/felangel/bloc/pull/2859#issuecomment-987233491

I think the best practice is to put the BlocProvider as low as it can go. Although, there is temptation to put it high and not think about it.

chonghorizons avatar Dec 07 '21 03:12 chonghorizons

@pandora-house I believe dependency injection in presentation layer is bad practice. I use service locator get_it for registering all dependencies. Blocs and cubits registration / unregistration I extract to injection container methods which I call from initState / dispose of according widget (for blocs holding local state) or AppWidget (for blocs holding global state). I do it this way because I need somewhere close blocs to prevent memory leaks and reset bloc local states. The disadvantage of this approach is creating stateful widgets instead of stateless. If someone knows better approach I would like to listen it.

@pandora-house and @meowofficial I think git_it and BlocProviders very high up is fine. But one can inject BlocProviders lower down in the widget tree.

https://github.com/chonghorizons/flutter_bloc_opinionated_practices/wiki/blocProvider-placed-as-low-as-possible

More generally, here are some discussions of "recommended" practices. There seems to be pushback against the phrasing of "best practice" because of any practice that works consistently is fine.

@chonghorizons

chonghorizons avatar Dec 23 '21 05:12 chonghorizons