Skip to main content

bloc-provider-bloc

Use when providing, accessing, and automatically disposing BLoC (Business Logic Component) instances across Flutter widget subtrees using bloc_provider.

跳到安装

来源信息

仓库
mono0926/bloc_provider
最近来源活动
2026年9月9日 03:08
检测到的 SKILL.md 语言
英语
星标
116
分支
16

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
bloc_provider-bloc
description
Use when providing, accessing, and automatically disposing BLoC (Business Logic Component) instances across Flutter widget subtrees using bloc_provider.
# bloc_provider BLoC Management Guide `bloc_provider` manages the lifecycle of BLoC (Business Logic Component) classes, providing $O(1)$ subtree lookups and automatic resource disposal when the enclosing widget tree unmounts. ## Guidelines - **Implementing the `Bloc` Interface**: - Always implement the `Bloc` interface on your business logic classes. - Implement `void dispose()` to close all active `StreamController`s, sinks, and subscriptions. - **Providing BLoCs**: - Wrap the target subtree with `BlocProvider<MyBloc>(creator: (context, bag) => MyBloc(), child: ...)`. - The BLoC is lazily created upon first access and automatically disposed when the provider's state unmounts. - **Accessing BLoCs**: - Call `BlocProvider.of<MyBloc>(context)` to retrieve the nearest ancestor BLoC. - Unlike standard InheritedWidget lookups that cause rebuilding, `BlocProvider.of()` does not trigger widget rebuilds itself; connect outputs to `StreamBuilder` widgets to rebuild only the necessary parts of the UI. ## Examples ### 1. Defining a BLoC ```dart import 'dart:async'; import 'package:bloc_provider/bloc_provider.dart'; import 'package:rxdart/rxdart.dart'; class CounterBloc implements Bloc { CounterBloc() { _incrementController.listen((_) { _countSubject.add(_countSubject.value + 1); }); } final _countSubject = BehaviorSubject<int>.seeded(0); final _incrementController = StreamController<void>(); ValueStream<int> get count => _countSubject; Sink<void> get increment => _incrementController.sink; @override void dispose() async { await _incrementController.close(); await _countSubject.close(); } } ``` ### 2. Providing and Consuming in the Widget Tree ```dart import 'package:bloc_provider/bloc_provider.dart'; import 'package:flutter/material.dart'; class CounterPage extends StatelessWidget { const CounterPage({super.key}); @override Widget build(BuildContext context) { return BlocProvider<CounterBloc>( creator: (context, bag) => CounterBloc(), child: const _CounterView(), ); } } class _CounterView extends StatelessWidget { const _CounterView(); @override Widget build(BuildContext context) { final bloc = BlocProvider.of<CounterBloc>(context); return Scaffold( appBar: AppBar(title: const Text('BLoC Counter')), body: Center( child: StreamBuilder<int>( stream: bloc.count, initialData: bloc.count.value, builder: (context, snapshot) { return Text( 'Count: ${snapshot.data}', style: Theme.of(context).textTheme.headlineMedium, ); }, ), ), floatingActionButton: FloatingActionButton( onPressed: () => bloc.increment.add(null), child: const Icon(Icons.add), ), ); } } ``` ## Common Pitfalls & Anti-Patterns - ❌ **Anti-pattern**: Forgetting to implement `void dispose()` in BLoC classes, causing stream controllers to leak in memory. - ✔️ **Correct**: Always close subjects and controllers inside `dispose()`. - ❌ **Anti-pattern**: Instantiating BLoC directly inside a `StatelessWidget.build()` method without `BlocProvider`. - ✔️ **Correct**: Use `BlocProvider(creator: ...)` to tie the BLoC's lifespan to the widget tree lifecycle.
在 GitHub 查看