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

Flutter自定义Widget调用setState后未刷新问题求助

问题:自定义CartCounter组件点击Reset后无法刷新

我创建了名为CartCounter的自定义Widget,但调用setState后该组件无法刷新。点击Reset按钮想将其值重置为0,但组件没有重建。请问需要对自定义Widget做什么修改,还是存在其他问题?

相关代码

HomeScreen2 代码

class _HomeScreen2State extends State<HomeScreen2> {
  int english = 0;
  int maths = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
            'English =' + english.toString() + ' Maths=' + maths.toString()),
      ),
      body: Column(
        children: [
          CartCounter(
              value: english,
              onChange: (value) {
                setState(() {
                  english = value;
                });
              }),
          CartCounter(
              value: maths,
              onChange: (value) {
                setState(() {
                  maths = value;
                });
              }),
          ElevatedButton(
            onPressed: () {
              setState(() {
                english = 0;
                maths = 0;
              });
            },
            child: Text('Reset'),
          ),
        ],
      ),
    );
  }
}

CartCounter 组件代码

class CartCounter extends StatefulWidget {
  final int value;
  final Function(int) onChange;
  const CartCounter({Key? key,required this.value,required this.onChange}) : super(key: key);

  @override
  State<CartCounter> createState() => _CartCounterState();
}

class _CartCounterState extends State<CartCounter> {
late int result;


@override
  void initState() {
    super.initState();
    result=widget.value;
  }


  @override
  Widget build(BuildContext context) {
    return Container(
      height: 80,
      width: 200,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20)
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
        IconButton(
            color: Colors.blue,
            onPressed: (){
              setState(() {
                result--;
                widget.onChange(result);
              });
            }, icon: Icon(Icons.remove)),
        SizedBox(width: 60,child: Center(child: Text(result.toString(),style: Theme.of(context).textTheme.headlineSmall,)),),
        IconButton(
            color: Colors.blue,
            onPressed: (){
              setState(() {
                result++;
                widget.onChange(result);
              });
            }, icon: Icon(Icons.add)),
      ],),
    );
  }
}

问题原因

CartCounter的内部状态result仅在initState中初始化了一次,而initState只会在组件首次创建时执行。当点击Reset按钮后,父组件的english和maths被重置为0,CartCounter的widget.value也随之更新,但组件内部的result并没有同步这个新值,因此组件不会触发重建,界面也就不会刷新。

解决方案

在_CartCounterState中重写didUpdateWidget方法,当父组件传递的value发生变化时,同步更新内部的result状态并触发重建:

class _CartCounterState extends State<CartCounter> {
  late int result;

  @override
  void initState() {
    super.initState();
    result = widget.value;
  }

  // 添加这个方法
  @override
  void didUpdateWidget(covariant CartCounter oldWidget) {
    super.didUpdateWidget(oldWidget);
    // 当widget.value和旧值不同时,更新result
    if (oldWidget.value != widget.value) {
      setState(() {
        result = widget.value;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    // 原build代码不变
    return Container(
      height: 80,
      width: 200,
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20)
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: [
          IconButton(
              color: Colors.blue,
              onPressed: (){
                setState(() {
                  result--;
                  widget.onChange(result);
                });
              }, icon: Icon(Icons.remove)),
          SizedBox(width: 60,child: Center(child: Text(result.toString(),style: Theme.of(context).textTheme.headlineSmall,)),),
          IconButton(
              color: Colors.blue,
              onPressed: (){
                setState(() {
                  result++;
                  widget.onChange(result);
                });
              }, icon: Icon(Icons.add)),
        ],),
    );
  }
}

这样修改后,当父组件的english或maths变化时,CartCounter会检测到widget.value的更新,同步内部状态并刷新界面,点击Reset按钮后就能正常重置数值了。

内容的提问来源于stack exchange,提问作者user22362195

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 22:27:36