我有一个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并需要重建窗口小部件的状态。
答案 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)
您是否不使用有状态窗口小部件?无状态小部件不打算那样使用。而且没有任何好处,我不明白为什么您会使事情变得过于复杂。