You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发Flutter测验应用遇报错:build过程中调用setState()/markNeedsBuild()

Flutter测验应用"setState() called during build"错误解决方法

错误原因

你的代码核心问题是:按钮的onPressed属性错误地直接执行了函数(带括号调用),而非传递函数引用。这会导致组件构建过程中就触发包含setState的函数,违反Flutter框架的构建规则,从而抛出错误。

问题具体出现在两个组件中:

  • Answer组件的ElevatedButton
  • Result组件的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 11:45:57