Flutter Bloc从其他小部件更改状态 [英] Flutter Bloc change state from different widget

查看:92
本文介绍了Flutter Bloc从其他小部件更改状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序主页上,我有一个列表视图,该列表视图在用户单击新页面时重新生成.我已经使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆