Flutter:我可以在 BLoC 架构中使用 setState() 吗?

Posted

技术标签:

【中文标题】Flutter:我可以在 BLoC 架构中使用 setState() 吗?【英文标题】:Flutter: can I use setState() with a BLoC architecture? 【发布时间】:2020-04-11 00:40:53 【问题描述】:

我对状态管理的理解是,单独调用setState() 会引发各种混乱的问题,代码文件会变得庞大且难以调试,并且会妨碍项目的合理结构。在小部件的外观发生轻微变化的情况下,使用像 BLoC 或 ScopedModel 这样的复杂架构来显示/隐藏小部件(例如)是没有意义的。但是,我的理解是不能将setState()和架构混在一起,否则架构的意义何在?

让我们使用 BLoC 来回答这个问题(只是因为我碰巧在使用它),特别是 this package。假设我有这个超级简单的示例代码:

class MyWidget extends StatefulWidget 
  @override
  void createState() 
    return _MyWidgetState();
  


class _MyWidgetState extends State<MyWidget>() 
  bool _isShowing = false;
  MyBloc bloc;

  @override
  void initState() 
    super.init();
    bloc = MyBloc();
  

  @override
  Widget build(BuildContext context) 
    return BlocBuilder(
      bloc: bloc,
      builder: (context, state) 
        return Column(
          children: <Widget>[
            Text(state.myText),
            if (_isShowing)
              Text("Button has been pressed!"),
            RaisedButton(
              child: Text("Show label"),
              onTap: () => setState(() => _isShowing = true),
            ),
            RaisedButton(
              child: Text("Run event"),
              onTap: () => bloc.add(NewEvent()),
            ),
          ],
        );
      ,
    );
  

在上面的粗略示例中,将 BLoC 模式与 setState() 混合是否正确/可接受?为什么我不使用 BLoC 来处理显示 Text 小部件?我在哪里画线?有什么优点/缺点?有性能差异吗?

注意:我不是在寻找“只需将两个 Text 小部件合并在一起”的答案。我正在寻找纯粹的建筑视角。

【问题讨论】:

AFAIK:BLoC 是将业务逻辑与 UI 部分分离的架构。如果需要,您可以随时将 setState 与 bloc 结合使用。 【参考方案1】:

你可以。

像 scoped_model/bloc/etc 这样的架构并不是要移除对 setState 的调用。 它们是关于分离关注点和简化实现

可以并且应该在有意义的情况下使用 setState,例如动画。

首先,即使是这些架构也使用 setState。你只是看不到它,但它就在那里

【讨论】:

以上是关于Flutter:我可以在 BLoC 架构中使用 setState() 吗?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 多个 Bloc 和 NamedRoutes

Flutter BLoC 架构 - 角色

如何在 Flutter 上实现 BLoC 模式的 TDD

Flutter 使用流“RxDart”提交登录 Bloc

Flutter BLOC 和 Provider 如何注册在一起

Flutter Bloc A 在 Bloc B 中添加流,但此流不会通过 StreamBuilder 在 UI 中呈现