StatelessWidget可以包含成员变量吗?

时间:2020-07-06 07:41:12

标签: flutter flutter-widget flutter-state statelesswidget

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

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

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并不是很清楚,只是说

对于可以动态变化的成分,例如由于具有内部时钟驱动状态,或者取决于某些系统状态,请考虑使用StatefulWidget。

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

2 个答案:

答案 0 :(得分:4)

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

不需要需要可变状态的小部件

此内容取自documentation。即使您只有一个非最终变量,也意味着实际上可以在窗口小部件中进行某些更改。这不是一门不变的课。理想情况下,您应该这样使用StatelessWidget

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

或类似的东西

class MyWidget extends StatelessWidget {
  const MyWidget();
}

当您拥有非最终变量时,请使用StatefulWidget。您的课程必须明确是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,因为必须在状态不可变的所有情况下使用它。

答案 1 :(得分:1)

您是否不使用有状态窗口小部件?无状态小部件不打算那样使用。而且没有任何好处,我不明白为什么您会使事情变得过于复杂。