Flutter Bloc 不断重建小部件而不改变状态

Posted

技术标签:

【中文标题】Flutter Bloc 不断重建小部件而不改变状态【英文标题】:Flutter Bloc keeps rebuilding widget without state changing 【发布时间】:2020-07-05 04:28:10 【问题描述】:

学习 Bloc 模式,我偶然发现了这一点。在第一页中,ExamBloc 处理获取检查和显示。用户选择考试后,将使用所选考试调用测验页面。 QuestionBloc 获取问题并将其传递给有状态小部件以显示问题。问题显示正确。

但是,整个页面无缘无故地不断重建。我尝试了 QuizScreen 小部件的有状态和无状态小部件,但仍然无法停止重建。感谢任何帮助。

´´´

 class _QuizScreenState extends State<QuizScreen> 
  @override
  Widget build(BuildContext context) 
    final QuestionBloc questionBloc = context.bloc<QuestionBloc>();
    questionBloc.add(FetchQuestion(widget.selectedExam));

    return
       BlocBuilder<QuestionBloc,QuestionState>(
         bloc: questionBloc,
         builder: (context, state) 
           print('entrance'+state.toString());
           if (state is QuestionIsLoading)
             return Center(child: CircularProgressIndicator());
           if (state is QuestionIsLoaded)
            final QuizBrain quizBrain =QuizBrain(state.questionList);
            List<QuestionModel> ql=state.questionList;
             return Scaffold(
                 body:  Choices(quizBrain: quizBrain, questionList: ql));
         ,
       );
  



class Choices extends StatefulWidget 

 Choices(@required this.quizBrain,@required this.questionList);
 final List<QuestionModel> questionList;
 final QuizBrain quizBrain;
  @override
  _ChoicesState createState() => _ChoicesState();


class _ChoicesState extends State<Choices> 
  var _selection;

  onChangedRB(String  value)  setState(()  _selection = value; );
  print('onchange clicked');
  print(value);
  widget.quizBrain.nextQuestion();
  
  @override
  Widget build(BuildContext context) 
    return  Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[

        Text(
          widget.quizBrain.getNextQuestion().content,
          textAlign: TextAlign.center,
          overflow: TextOverflow.ellipsis,
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
        Container(child: RB(choice:widget.quizBrain.getNextQuestion().content,value:'A',groupValue:_selection,onChanged:onChangedRB
        )),


      ],
    );

  

´´´

【问题讨论】:

【参考方案1】:

你正在无限循环:

在您的构建器中,您正在添加新事件。解析事件后,它会添加状态并将此状态传递给构建器:

BlocBuilder 正在监听 QuestionBloc 状态变化。使用 BlocProvider 您正在添加事件,该事件将新状态添加到 BlocBuilder

长话短说,你不应该添加相同类型的 Bloc 事件

(BlocProvider.of&lt;QuestionBloc&gt;(context).add(FetchQuestion(widget.selectedExam)))

在同一个 Bloc 构建器中 (BlocBuilder&lt;QuestionBloc,QuestionState&gt;)。

【讨论】:

我做了你推荐的改变,我得到了这个错误。 BlocProvider.of() 使用不包含问题 Bloc 类型的 Bloc 的上下文调用。从传递给的上下文开始找不到祖先 BlocProvider 必须是您从中调用 questionBloc.add 的小部件的父级

以上是关于Flutter Bloc 不断重建小部件而不改变状态的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Bloc 不会改变 TextFormField 的初始值

在 Flutter 中使用 BLoC - 在有状态小部件与无状态小部件中的使用

Flutter Bloc 状态管理

Flutter 不会使用不同的参数重建相同的小部件

三元条件没有重建我的小部件 - Flutter

Flutter 重建父小部件