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

Flutter中如何通过传入对象的参数函数修改该对象的属性

解决方案

一、实现点击按钮自动更新文本效果

Flutter采用单向数据流的状态驱动UI设计,你目前的写法中MyButton内部的myString仅在initState阶段初始化一次,后续父组件传入的myText变化不会自动同步,有两种常用实现方案:

方案1:状态提升(官方推荐)

将文本状态放在父组件MyButtonRow中管理,子组件仅负责接收参数展示、触发点击回调,代码修改如下:

class MyButtonRow extends StatefulWidget {
  const MyButtonRow({Key? key}) : super(key: key);

  @override
  _MyButtonRowState createState() => _MyButtonRowState();
}

class _MyButtonRowState extends State<MyButtonRow> {
  // 父组件管理按钮文本状态
  late String _currentBtnText;

  @override
  void initState() {
    super.initState();
    _currentBtnText = "Hello";
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      child: Row(
        children: <Widget>[
          MyButton(
            onTap: (){
              print("Notify me");
              // 父组件直接修改状态刷新UI
              setState(() {
                _currentBtnText = "更新后的文本";
              });
            },
            myText: _currentBtnText,
          ),
        ],
      ),
    );
  }
}

// 子组件改为无状态组件,仅接收参数渲染即可
class MyButton extends StatelessWidget {
  final Function onTap;
  final String myText;
  const MyButton({Key? key, required this.onTap, required this.myText}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: onTap,
      child: Text(myText)
    );
  }
}

方案2:子组件内部管理状态

如果文本状态不需要父组件感知,可将更新逻辑封装在MyButton内部,点击时先执行内部更新逻辑,再执行父组件传入的回调:

// MyButtonRow代码无需修改,仅修改MyButton部分
class MyButton extends StatefulWidget {
  final Function onTap;
  final String initText;
  const MyButton({Key? key, required this.onTap, required this.initText}) : super(key: key);

  @override
  _MyButtonState createState() => _MyButtonState();
}

class _MyButtonState extends State<MyButton> {
  late String myString;

  @override
  void initState() {
    myString = widget.initText;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: (){
        // 先执行内部更新逻辑
        setState(() {
          myString = "更新后的文本";
        });
        // 再执行父组件传入的回调
        widget.onTap.call();
      },
      child: Text(myString)
    );
  }
}

二、父组件MyButtonRow访问MyButton属性的方法

不推荐直接访问子组件内部属性,该做法会导致组件耦合度升高,状态难以维护,优先选择上述状态提升/回调方案。
如果特殊场景必须实现,可以通过GlobalKey获取子组件的State实例进行访问,实现代码如下:

class MyButtonRow extends StatefulWidget {
  const MyButtonRow({Key? key}) : super(key: key);

  @override
  _MyButtonRowState createState() => _MyButtonRowState();
}

class _MyButtonRowState extends State<MyButtonRow> {
  // 定义GlobalKey绑定MyButton的State
  final GlobalKey<_MyButtonState> _myBtnKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      child: Row(
        children: <Widget>[
          MyButton(
            key: _myBtnKey, // 给子组件绑定key
            onTap: (){
              print("Notify me");
              // 通过key访问子组件的属性,修改后手动触发刷新
              _myBtnKey.currentState?.setState(() {
                _myBtnKey.currentState?.myString = "修改后的文本";
              });
            },
            myText: "Hello",
          ),
        ],
      ),
    );
  }
}

// 注意:如果MyButton和MyButtonRow在不同文件,需要把_MyButtonState的下划线去掉改为公开类
class MyButton extends StatefulWidget {
  final Function onTap;
  final String myText;
  const MyButton({Key? key, required this.onTap, required this.myText}) : super(key: key);

  @override
  _MyButtonState createState() => _MyButtonState();
}

class _MyButtonState extends State<MyButton> {
  late Function onTap;
  late String myString;
  @override
  void initState() {
    onTap = widget.onTap;
    myString = widget.myText;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: onTap,
      child: Text(myString)
    );
  }
}

注意:该方式仅适合临时特殊场景使用,生产环境优先使用状态提升方案保证数据流清晰可维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:15:08