BLoC:多次调用监听回调

Posted

技术标签:

【中文标题】BLoC:多次调用监听回调【英文标题】:BLoC: listen callback called multiple times 【发布时间】:2019-10-24 10:09:42 【问题描述】:

我有一个有状态的小部件,它从其父级获取一个块:

class Page extends StatefulWidget 
  @override
  State<StatefulWidget> createState() =>
  _PageState();


class _PageState extends State<Page> 
  final TextEditingController mnemonicController = TextEditingController();
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) 

final MnemonicLogicBloc mnemonicLogicBloc =
BlocProvider.of<MnemonicLogicBloc>(context);

mnemonicLogicBloc.outCheckMnemonic.listen((isCorrect)
  if (!isCorrect) 
    SnackBar copySnack = SnackBar(content: Text('Wrong Mnemonic!'));
    _scaffoldKey.currentState.showSnackBar(copySnack);
  
);

return Scaffold(
    key: _scaffoldKey,
    body: Container(
      width: double.infinity,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Container(
            child: TextField(
              controller: mnemonicController,
            ),
          ),
          RaisedButton(
            onPressed: () 
              mnemonicLogicBloc.isMnemonicCorrect(mnemonicController.text);
            ,
            child: Text('Check', style: TextStyle(color: Colors.white)),
          )
        ],
      ),
    ));


我想要做的是检查,当用户按下按钮时,插入的字符串是否正确。我在集团中调用的方法是:

void isMnemonicCorrect(String typedMnemonic)
if(typedMnemonic == _lastGeneratedMnemonic)
  _inCheckMnemonic.add(true);
else
  _inCheckMnemonic.add(false);
 

_inCheckMnemonic 是我的主题的接收器(我正在使用 rxDart),而 outCheckMnemonic 是我的流。问题是,即使 bloc 的 'isCorrect' 方法被调用一次,listen 回调也被调用了两次(SnackBar 显示了两次)。为什么会这样?

编辑:我只需使用 Navigator.push 导航到 Page():

Navigator.of(context).push(MaterialPageRoute(
                            builder: (BuildContext context) 
                return Page();
));

我能够检索 bloc,因为当我的应用启动时,我初始化了 bloc:

return runApp(BlocProvider<ApplicationBloc>(
bloc: ApplicationBloc(),
child: BlocProvider<MnemonicLogicBloc>(
  bloc: MnemonicLogicBloc(),
  child: BlocProvider<HomePageBloc>(
    bloc: HomePageBloc(),
    child: App(),
  ),
)

));

【问题讨论】:

调用Page小部件时添加代码 @diegoveloper 完成 尝试进行此更改,将您的 Page() 声明为 builder: 函数之外的变量,然后使用该变量。最后一页 = Page(); Navigator.of .... builder: (BuildContext context) => page) .... 并检查它是否有效 现在好像可以了。但为什么呢? 你爱上了***.com/questions/52249578/…。您使用 BlocProvider 的方式是不安全的,您应该创建一个有状态的小部件。 【参考方案1】:

当您在 Navigator 中添加新的 Widget 时,请避免在构建器中创建该小部件,而是在外部声明一个变量并在您的构建器中重用该变量,如下所示:

final page = Page();
Navigator.of(context).push(MaterialPageRoute(
                            builder: (BuildContext context) => page ), );

通过此更改,我们避免了以意想不到的方式多次重新创建我们的小部件。

【讨论】:

但这不也占用了所有的内存和其他资源吗?

以上是关于BLoC:多次调用监听回调的主要内容,如果未能解决你的问题,请参考以下文章

Flutter bloc 模式多次重复调用函数

使用 forEach 时避免回调多次调用

多次调用 Cakephp 回调函数

如何修复“多次调用写回调”

Dart/Flutter - 回调函数的收益

运行 npm install 时多次调用回调