1

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

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

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 和重绘任何内容,它仅用于检查按下“关闭”按钮时是否对任何复选框进行了修改。

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

我没有发现文档对此非常清楚,它只是说

对于可以动态更改的组合,例如由于具有内部时钟驱动状态或取决于某些系统状态,请考虑使用 StatefulWidget。

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

4

2 回答 2

4

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

不需要可变状态的小部件

这是从documentation. 即使您有一个非最终变量,这也意味着您的小部件中实际上可以更改某些内容。它不是一个不可变的类。理想情况下,您应该StatelessWidget像这样使用 s:

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),所以它不能是 a ,因为它必须在状态不可变StatelessWidget的所有情况下使用。

于 2020-07-06T07:47:11.813 回答
1

您是否有任何理由不使用有状态小部件?无状态小部件不打算以这种方式使用..而且没有任何好处,我不明白你为什么让事情过于复杂..

于 2020-07-06T07:46:09.297 回答