开发Flutter测验应用遇报错:build过程中调用setState()/markNeedsBuild()
Flutter测验应用"setState() called during build"错误解决方法
错误原因
你的代码核心问题是:按钮的onPressed属性错误地直接执行了函数(带括号调用),而非传递函数引用。这会导致组件构建过程中就触发包含setState的函数,违反Flutter框架的构建规则,从而抛出错误。
问题具体出现在两个组件中:
Answer组件的ElevatedButtonResult组件的TextButton
修复步骤
1. 修复Answer组件
原代码中onPressed直接调用函数:
onPressed: selectHandler(),
修改为传递函数引用(去掉括号):
onPressed: selectHandler,
修复后的完整Answer组件代码:
import 'package:flutter/material.dart'; class Answer extends StatelessWidget { final Function selectHandler; final String answerText; const Answer(this.selectHandler, this.answerText, {Key? key}) : super(key: key); @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, child: ElevatedButton( onPressed: selectHandler, style: ButtonStyle( textStyle: MaterialStateProperty.all(const TextStyle(color: Colors.white)), backgroundColor: MaterialStateProperty.all(Colors.green)), child: Text(answerText), ), ); } }
2. 修复Result组件
原代码中onPressed直接调用函数:
onPressed: resetHandler(),
修改为传递函数引用:
onPressed: resetHandler,
修复后的完整Result组件代码:
// ignore_for_file: avoid_print import 'package:flutter/material.dart'; class Result extends StatelessWidget { final int resultScore; final Function resetHandler; const Result(this.resultScore, this.resetHandler, {Key? key}) : super(key: key); String get resultPhrase { String resultText; if (resultScore >= 41) { resultText = '你太棒了!'; print(resultScore); } else if (resultScore >= 31) { resultText = '很不错哦!'; print(resultScore); } else if (resultScore >= 21) { resultText = '还需要再加把劲!'; } else if (resultScore >= 1) { resultText = '你得努力学习了!'; } else { resultText = '这个成绩不太理想!'; print(resultScore); } return resultText; } @override Widget build(BuildContext context) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( resultPhrase, style: const TextStyle(fontSize: 26, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), Text( '得分: $resultScore', style: const TextStyle(fontSize: 36, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), TextButton( onPressed: resetHandler, child: Container( color: Colors.green, padding: const EdgeInsets.all(14), child: const Text( '重新开始测验', style: TextStyle(color: Colors.white), ), ), ), ], ), ); } }
关键注意事项
Flutter中onPressed这类回调属性要求接收函数引用(不带括号的函数名,或匿名函数),而非直接执行函数。如果直接带括号调用函数,会在组件构建阶段立即执行该函数,若函数内部包含setState,就会触发本次错误——因为框架正在构建组件时不允许修改状态。
内容的提问来源于stack exchange,提问作者HOPE
相关产品推荐
相关产品推荐

