As your Flutter app grows, you'll often need to provide multiple blocs to different parts of the widget tree. Nesting BlocProvider widgets works, but can lead to deeply indented code. MultiBlocProvider solves this by combining multiple providers into a single widget, improving readability and maintainability.
What is MultiBlocProvider?
MultiBlocProvider is a convenience widget that merges multiple BlocProvider widgets into one. It takes a list of providers and a single child, effectively flattening the widget tree. Internally, it nests the providers in the order they are given, but without the visual indentation.
When to Use MultiBlocProvider
- Top-level app setup – Provide global blocs (e.g.,
AuthBloc,ThemeBloc) near the root. - Feature modules – Group all blocs needed for a feature in one place.
- Any time you have 2+ BlocProviders – Improves readability and reduces nesting.
Basic Usage
Replace nested BlocProvider widgets with MultiBlocProvider. The order of providers matters: they are applied from top to bottom, so later providers can depend on earlier ones.
Nesting vs MultiBlocProvider
While MultiBlocProvider is cleaner, sometimes you still need explicit nesting for scoping reasons. For example, if you want a bloc to be available only inside a specific subtree, you might nest a BlocProvider inside a child of a MultiBlocProvider. The two approaches can be combined.
Scoping with MultiBlocProvider
Each BlocProvider in the list creates its own scope. Blocs are available to all descendants of the MultiBlocProvider. If you need a bloc only in a part of the tree, place the MultiBlocProvider at the appropriate level.
Combining with Other Bloc Widgets
MultiBlocProvider works seamlessly with other bloc widgets like BlocBuilder, BlocListener, and BlocConsumer. You can also combine it with MultiRepositoryProvider if you need to provide repositories.
Performance Considerations
MultiBlocProvider does not add any runtime overhead compared to nested providers – it simply reorganises the code. The create functions are called only once when the widget is inserted, so there's no performance penalty. However, be mindful of creating blocs that are never used; provide them only where needed.
Best Practices
- Group related blocs – Keep providers together in a
MultiBlocProviderat the feature or app level. - Maintain order – Ensure dependent blocs come after the blocs they depend on in the
providerslist. - Use for root providers – Place global blocs (auth, theme) in a
MultiBlocProvideraboveMaterialApp. - Combine with
MultiRepositoryProvider– Keep DI clean by grouping both blocs and repositories. - Avoid over-providing – Don't provide a bloc at the top if it's only needed in one branch; scope it lower.
Common Mistakes
- ❌ Incorrect order – Placing a bloc that depends on another before it in the list will cause a
ProviderNotFoundException. - ❌ Providing too many blocs globally – Increases memory usage and can lead to unintended state sharing.
- ❌ Forgetting to use
MultiBlocProviderfor multiple providers – Leads to deeply nested code that is hard to read. - ❌ Creating a bloc inside
buildinside the provider – Ensurecreateis a function that returns a new instance, not an existing one.
What's Next?
Now that you can manage multiple blocs efficiently, learn how to test them and handle more advanced scenarios like dependency injection with get_it.
Next, explore Bloc testing and Dependency injection with get_it.