StatelessWidget 可以包含成员变量吗?

Can a StatelessWidget contain member variables?

我有一个 StatelessWidget,它使用 ScopedModel 来存储它的数据。该小部件基本上显示了一个复选框列表和一些用于保存复选框状态的按钮。

现在我想跟踪用户是否更改了任何复选框,即自小部件显示以来 checked/unchecked 它们。所以我添加了这样的内容:

class MyCheckboxScreen extends StatelessWidget{

    bool _hasBeenModified = false;

    void _itemCheckedChange(bool checked, MyModel model){
        _hasBeenModified = true;

        // Code to change the model here
    }


    void _onCloseButton(){
        if( _hasBeenModified ){
            // Show a warning that there are modifications that will not be be saved
        }
    }


    void _onSaveButton(Context context, MyModel model){
        model.save();
        Navigator.of(context).pop();
    }

}

这似乎可行,但我的 StatelessWidget 现在包含了它自己的状态。

该状态不用于更新 UI 和重绘任何内容,它仅用于检查按下“关闭”按钮时是否对任何复选框进行了修改。

StatelessWidget 拥有这种内部状态安全吗?或者这可能是个问题?例如,小部件是否会意外重新创建,内部状态丢失?

我没发现the documentation对此很清楚,它只是说

For compositions that can change dynamically, e.g. due to having an internal clock-driven state, or depending on some system state, consider using StatefulWidget.

但这听起来只适用于影响 UI 并且需要重建小部件的状态。

您有什么理由不使用有状态小部件吗?无状态小部件不打算以这种方式使用..而且没有任何好处,我不明白为什么你把事情搞得太复杂了..

是的,StatelessWidget 可以有可变变量(您的代码可以编译),但这是错误的。

A widget that does not require mutable state

本文摘自documentation。即使您只有一个非最终变量,也意味着实际上可以在您的小部件中更改某些内容。它不是不可变的 class。理想情况下,您应该像这样使用 StatelessWidgets:

class MyWidget extends StatelessWidget {
  final int a;
  final String b;
  const MyWidget(this.a, this.b);
}

或类似的内容,例如

class MyWidget extends StatelessWidget {
  const MyWidget();
}

当你有非 final 变量时,使用 StatefulWidget。您的 class 显然必须是 StatefulWidget:

// This is not final. It can be changed (and you will change it)
// so using the stateless way is wrong
bool _hasBeenModified = false;

void _itemCheckedChange(bool checked, MyModel model){
  _hasBeenModified = true;
}

UI 实际上并不重要,因为这是变量和可变性的问题。某些东西正在发生变化 (bool _hasBeenModified),所以它不能是 StatelessWidget,因为它必须在所有状态为 immutable.[=22= 的情况下使用]