Flutter Bloc从其他小部件更改状态 [英] Flutter Bloc change state from different widget
问题描述
在我的应用程序主页上,我有一个列表视图,该列表视图在用户单击新页面时重新生成.我已经使用flutter_bloc插件实现了块模式,但是我不知道如何从另一个窗口小部件更改状态.
On my apps home page, I have a list view that rebuilds whenever the user clicks on a new page. I have implemented the block pattern using the flutter_bloc plugin but I don't know how to change the state from another widget.
推荐答案
要用flutter bloc更改状态,必须牢记两件事:
Two things you will have to keep in mind for changing state with flutter bloc:
- 集团的依赖注入(DI).
- 与您的bloc实例的交互.
情况1.您需要在一条路径内为小部件子树提供块.
要向一个子树中的多个窗口小部件提供bloc的单个实例,请使用 BlocProvider
小部件.它会创建bloc实例,并在需要时自动处理它,并通过 BlocProvider.of< T>(上下文)
向其子节点提供bloc,其中 T
是您的bloc的名称:
To provide a single instance of a bloc to multiple widgets within a subtree you use BlocProvider
widget. It creates bloc instance, automatically disposes of it when needed and provides bloc to its children via BlocProvider.of<T>(context)
, where T
is the name of your bloc:
BlocProvider(
create: (BuildContext context) => BlocA(),
child: ChildA(),
);
请记住,默认情况下,它是使用属性 lazy:true
创建的,表示 create:(BuildContext context)=>BlocA()
将在调用 BlocProvider.of< T>(上下文)
之后执行.如果您不想要,请预先设置 lazy:false
.
Keep in mind, that by deafult it is created with property lazy: true
, means that create: (BuildContext context) => BlocA(),
will be executed after invoke of BlocProvider.of<T>(context)
. If you dont want it - set lazy: false
in advance.
情况2.您需要为来自另一条路线(到另一上下文)的小部件提供块.
BlocProvider
会自动处置具有实例化的新路由上下文的bloc实例,但是如果使用 BlocProvider.value
:
BlocProvider
automatically disposes of a bloc instance with context of new route instantiated, but that will not happen if you use BlocProvider.value
:
BlocProvider.value(
value: BlocProvider.of<BlocA>(context),
child: ScreenA(),
);
重要说明: BlocProvider.value
仅应用于为新的子树提供现有实例,而不用它创建Bloc实例
Important note: BlocProvider.value
should only be used for providing existing instances to new subtree, do not create Bloc instance with it
从 bloc v6.1.0
开始 context.bloc
和 context.repository
开始不推荐使用,而推荐使用 context.read
和 context.watch
.
Starting from bloc v6.1.0
context.bloc
and context.repository
are deprecated in favor of context.read
and context.watch
.
context.select
允许基于部分集团状态更新UI:
context.select
allows to update UI based on a part of a bloc state:
final name = context.select((UserBloc bloc) => bloc.state.user.name);
context.read
使用BuildContext访问集团,并且不进行重建. context.watch
从其类型最接近的祖先提供者那里获取一个值,并订阅该提供者.
context.read
access a bloc with a BuildContext and do not result rebuilds.
context.watch
gets a value from the nearest ancestor provider of its type and subscribes to the provider.
访问集团的状态
如果您需要重新构建窗口小部件,以更改bloc值,请使用 context.watch
或 BlocBuilder
:
If you need a widget rebuilding due bloc value changing use context.watch
or 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:
Use context.read:
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => context.read<MyBloc>().add(MyEvent()),
...
)
}
这篇关于Flutter Bloc从其他小部件更改状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!