【问题标题】:How to update the state of Parent Widget from its Child Widget while also updating the Child's state in Flutter?如何从 Child Widget 更新 Parent Widget 的状态,同时在 Flutter 中更新 Child 的状态?
【发布时间】:2020-05-07 00:42:12
【问题描述】:

我想请你帮忙。

我下面的示例代码旨在从子小部件更新父小部件的状态,同时更新子小部件的状态。 Parent Widget 的文本值会更新,同时还会更改 Child Widget 按钮的颜色。

import 'package:flutter/material.dart';

void main() => runApp(AppIndex());

class AppIndex extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: ParentWidget());
  }
}

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  String _textValue = 'Old Value';

callback(newValue){
  setState(() {
    _textValue = newValue;
  });
}

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text(_textValue),
        ChildWidget(),
      ],
    );
  }
}

class ChildWidget extends StatefulWidget {
  String textValue;
  Function callback;

  ChildWidget({this.textValue, this.callback});

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

class _ChildWidgetState extends State<ChildWidget> {
  bool buttonState = false;

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      color: buttonState == true ? Colors.greenAccent : Colors.redAccent,
      child: Text('Update State'),
      onPressed: () {
        setState(() {
          if (buttonState == false) {
            buttonState = true;
          } else if (buttonState == true) {
            buttonState = false;
          }
        });

        widget.callback('New Value');
      },
    );
  }
}

到目前为止,它能够做的是更新子小部件的颜色/状态,但是,父小部件似乎没有更新其状态。我的原始代码实际上只更新了 Parent 的 State 而不是 Parent 和 Child (相同的概念和关注点)。

上面的示例代码是我在问这里之前的初步研究结果的衍生产品。

我认为我的代码结构一定有问题,或者根据我的制作方式,这在 Flutter 的架构中是不可能的。如果可能的话,你能给我你对具有相同行为的东西的建议吗? (更新父子状态)

抱歉,我是这种类型的编程和架构的新手。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    欢迎使用 Flutter!似乎您没有将回调传递给子小部件。实例化 ChildWidget 时,您应该执行 new ChildWidget(callback: this.callback); 然后您可以通过 widget 属性从 State&lt;ChildWidget&gt; 类访问来自 StatefulWidget 的值,例如widget.callback.

    另外,值得注意的是,您应该尽量避免使用 Function 类型,因为它并没有真正提供有关函数将返回什么或它将作为参数的信息。为此,Dart 使用 typedef 关键字。例如,对于一个接受日期字符串并返回日期的函数(这是一个有点做作的例子,鉴于 Darts 对日期的出色内置支持),您可以执行以下操作:

    typedef Date StringToDateParser(String datestring);

    然后,在您的班级中,您可以使用StringToDateParser 作为类型。

    import 'package:flutter/material.dart';
    
    void main() => runApp(AppIndex());
    
    class AppIndex extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: ParentWidget());
      }
    }
    
    class ParentWidget extends StatefulWidget {
      @override
      _ParentWidgetState createState() => _ParentWidgetState();
    }
    
    class _ParentWidgetState extends State<ParentWidget> {
      String _textValue = 'Old Value';
    
      callback(newValue){
        setState(() {
          _textValue = newValue;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            Text(_textValue),
            ChildWidget(callback: this.callback, this._text),
          ],
        );
      }
    }
    
    class ChildWidget extends StatefulWidget {
    
      Function callback;
    
      ChildWidget({this.textValue, this.callback});
    
      @override
      _ChildWidgetState createState() => _ChildWidgetState();
    }
    
    class _ChildWidgetState extends State<ChildWidget> {
      bool buttonState = false;
    
      _ChildWidgetState();
    
      @override
      Widget build(BuildContext context) {
        return RaisedButton(
          color: buttonState == true ? Colors.greenAccent : Colors.redAccent,
          child: Text('Update State'),
          onPressed: () {
            setState(() {
              if (buttonState == false) {
                buttonState = true;
              } else if (buttonState == true) {
                buttonState = false;
              }
            });
    
            widget.callback('New Value');
          },
        );
      }
    }
    

    【讨论】:

    • 非常感谢!那很快。我现在意识到我的错误,你知道我发誓同样的事情似乎不适用于我的实际代码(即概念)。您的建议让我再次查看它(经过大量查找之后)并发现它有效。
    • 希望这不是太多,但你能用你提到的状态传播给我更多启发吗? :)
    • 哈哈哈,这就是编程的祸根,代码在别人看到之前永远不会工作,然后噗!神奇地它开始工作:)祝你好运。颤振惊人。
    • 当然,让我更新我的答案,在更正后的编辑中包含您的代码。
    • 我已经尝试过了,看看你现在的意思,但是传递回调(就像你提到的那样)并通过 this.callback() 调用它而不是调用它通过 widget.callback() 像我一样吗?我最初学到的是我写下来的东西,也许我可以通过这个改进我的代码。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 2023-04-09
    • 2021-02-11
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    相关资源
    最近更新 更多