如何确定作为参数传递给子小部件的函数的范围?

How to determine the scope of a function passed as a parameter to a child widget?

提问人:learner_bee 提问时间:8/30/2023 最后编辑:learner_bee 更新时间:8/31/2023 访问量:46

问:

我正在尝试了解我作为参数传递给子小部件的函数如何能够更新父小部件的实例属性。

例如,以下代码有效:

//...some code
DesignedContainer(
  colour: selectedGender == Gender.male
    ? activeCardColor
    : inactiveCardColor,
  cardChild: const GenderWidget(
    genderIcon: FontAwesomeIcons.mars,
    genderName: 'MALE',
  ),
  stateReset: () { //Note this function, I will change this below
    setState(() {
    selectedGender = Gender.male;
   });
  },
),
//...some code
class DesignedContainer extends StatefulWidget {
  const DesignedContainer({
    this.colour = const Color(0xFF1D1E33),
    this.cardChild,
    this.stateReset,
    super.key,
  });
  final Widget? cardChild;
  final Color colour;
  final VoidCallback? stateReset;

  @override
  State<DesignedContainer> createState() => _DesignedContainerState();
}

class _DesignedContainerState extends State<DesignedContainer> {
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: widget.stateReset, //I shall change this too
      child: Container(
        margin: const EdgeInsets.all(15.0),
        decoration: BoxDecoration(
          color: widget.colour,
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: widget.cardChild,
      ),
    );
  }
}

而如果我更改上面的代码,以便将 setState 移动到 DesignedContainer 小部件,如下所示:

//Inside the parent widget:
stateReset: () => selectedGender = Gender.male,
//some code

//Inside the child widget:
onTap: (){
    setState(() {
        widget.stateReset!();
    });
}

我正在使两个版本都起作用,而后者不起作用。我不明白为什么。

颤振 函数 dart 范围 参数传递

评论

0赞 offworldwelcome 8/31/2023
在第一个版本中,位于有状态小部件中。指定 时,您将捕获对有状态小部件的引用。但是,在第二个示例中,您调用的是 的 instead.这些是不一样的,第一个重建其关联的小部件,第二个重建 .DesignedContainerstateReset: () => setState(...)setStatesetState DesignedContainerDesignedContainer
0赞 learner_bee 8/31/2023
现在我明白了。谢谢!你为什么不把这个作为答案加进去?
0赞 offworldwelcome 8/31/2023
这不是一个非常详细的答案,但我在下面为您提供了一个更好的答案。

答:

1赞 offworldwelcome 8/31/2023 #1

在第一个版本中,位于有状态小部件中;让我们用关联的 .因此,当您指定:DesignedContainerMyWidgetMyWidgetState

stateReset: () => setState(...),

指的是 .为什么?setStateMyWidgetState.setState

“闭包是一个函数对象,它可以访问其词法范围内的变量,即使函数在其原始范围之外使用也是如此。函数可以关闭在周围作用域中定义的变量。

来源:https://dart.dev/language/functions#lexical-closures

周围的范围是 的方法。在该作用域中,您可以访问该方法,然后在传递给参数的函数的词法作用域中捕获该方法。buildMyWidgetStateMyWidgetState.setStatestateReset

由于这是可用的,因为即使在函数的原始范围之外使用函数时,词法作用域也可用,因此调用会从其他小部件正确调用。MyWidgetState.setState


在第二个示例中,您调用的是 的 。setStateDesignedContainer.setState

这些是不一样的,第一个重建其关联的小部件,第二个重建 DesignedContainer。

你可以解释为什么在第一种情况下使用相同的原则。