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

问题描述 投票:0回答:1

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

例如,以下代码有效:

//...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!();
    });
}

我希望两个版本都能工作,但后者不起作用。我不明白为什么。

flutter function dart scope parameter-passing
1个回答
0
投票

在第一个版本中,

DesignedContainer
位于有状态小部件内;我们将其称为
MyWidget
以及关联的
MyWidgetState
。因此,当您指定:

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

setState
指的是
MyWidgetState.setState
。为什么?

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

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

周围范围就是

build
MyWidgetState
方法。在该作用域中,您可以访问
MyWidgetState.setState
方法,然后在传递给
stateReset
参数的函数的词法作用域中捕获该方法。

由于词法作用域可用,因此可用 即使该函数在其原始作用域之外使用,该调用也会正确地从其他小部件调用

MyWidgetState.setState


在第二个示例中,您将调用

setState
DesignedContainer.setState

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

您可以推理为什么对第一种情况使用相同的原则。

© www.soinside.com 2019 - 2024. All rights reserved.