BLoC PatternEasy20 XP3 min read
How do you provide and access a Bloc in the widget tree?
TL;DR: Use BlocProvider to create and provide a Bloc to descendants. Access it with context.read<MyBloc>() (no rebuild) or context.watch<MyBloc>() (subscribes to changes). Use MultiBlocProvider at the app level for multiple blocs.
Full Answer
- ▸BlocProvider: Creates a bloc and provides it down the tree, auto-closes it when removed
- ▸BlocProvider.value: Provides an existing bloc instance (e.g., from a parent route) — does NOT close it
- ▸context.read<B>(): Get the bloc without subscribing — use inside callbacks
- ▸context.watch<B>(): Get + subscribe — use inside build() to rebuild on state change
- ▸context.select<B, T>(): Subscribe only to a specific field — minimizes rebuilds
- ▸MultiBlocProvider: Flattens nested BlocProviders
Code Examples
dartBlocProvider + access patterns
Output
// context.read: no rebuild — perfect for event dispatch // context.watch: rebuilds on every state change // context.select: rebuilds only when selected value changes
Common Mistakes
- ✗Using context.watch() inside a button's onPressed — context.read() is correct there
- ✗Nesting BlocProviders instead of using MultiBlocProvider — creates deeply indented code
Interview Tip
💡
Explain context.select() — it's the most granular option and prevents unnecessary rebuilds when only part of the state matters.
#bloc-provider#repository-provider#multi-bloc-provider#context