【发布时间】:2021-06-17 11:46:40
【问题描述】:
在我的应用主页上,我有一个列表视图,只要用户点击一个新页面,它就会重建。 我已经使用 flutter_bloc 插件实现了块模式,但我不知道如何从另一个小部件更改状态。
【问题讨论】:
在我的应用主页上,我有一个列表视图,只要用户点击一个新页面,它就会重建。 我已经使用 flutter_bloc 插件实现了块模式,但我不知道如何从另一个小部件更改状态。
【问题讨论】:
使用颤振块更改状态时必须记住两件事:
案例 1. 您需要在一个路由中为小部件子树提供 bloc。
要为子树中的多个小部件提供一个块的单个实例,请使用BlocProvider 小部件。它创建 bloc 实例,在需要时自动处理它,并通过 BlocProvider.of<T>(context) 向其子级提供 bloc,其中 T 是您的 bloc 的名称:
BlocProvider(
create: (BuildContext context) => BlocA(),
child: ChildA(),
);
请记住,默认情况下它是使用属性lazy: true 创建的,这意味着create: (BuildContext context) => BlocA(), 将在调用BlocProvider.of<T>(context) 之后执行。如果您不想要,请提前设置lazy: false。
案例 2。您需要从另一个路由(到另一个上下文)为小部件提供 bloc。
BlocProvider 自动处理一个带有实例化新路由上下文的 bloc 实例,但如果您使用 BlocProvider.value,则不会发生这种情况:
BlocProvider.value(
value: BlocProvider.of<BlocA>(context),
child: ScreenA(),
);
重要提示:BlocProvider.value 只能用于将现有实例提供给新的子树,不要用它创建 Bloc 实例
从 bloc v6.1.0 开始,context.bloc 和 context.repository 已弃用,取而代之的是 context.read 和 context.watch。
context.select 允许根据块状态的一部分更新 UI:
final name = context.select((UserBloc bloc) => bloc.state.user.name);
context.read 使用 BuildContext 访问一个块并且不会导致重建。
context.watch 从其类型的最近祖先提供者处获取值并订阅提供者。
访问集团的状态
如果您需要重建由于块值更改而导致的小部件,请使用context.watch 或BlocBuilder:
// Using context.watch at the root of the build method will result in the entire widget being rebuilt when the bloc state changes.
@override
Widget build(BuildContext context) {
final state = context.watch<MyBloc>().state;
return Text('$state');
}
或BlocBuilder:
// If the entire widget does not need to be rebuilt, either use BlocBuilder to wrap the parts that should rebuild
@override
Widget build(BuildContext context) {
return BlocBuilder<MyBloc, MyState>(
builder: (context, state) => Text('$state'),
);
}
访问集团以便添加事件
使用 context.read:
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => context.read<MyBloc>().add(MyEvent()),
...
)
}
【讨论】:
您可以将 BlocProvider 放置到一个通用的 ansestor 中,例如作为 MaterialApp 小部件的父级,或者您可以将 bloc 传递到您的新页面,如下所示:
BlocProvider.value(
value: BlocProvider.of<BlocA>(context),
child: ScreenB(),
);
【讨论】: