在Flutter中何时使用setState?

Yea*_*508 8 android dart flutter

作为扑朔迷离的新手,setStateFlutter应用程序中使用时,这让我非常困惑。在下面的代码中searching,在boolean 和var中resBody使用了setState。我的问题是,为什么只有searchingresBody里面的setState?为什么其他人没有名气?

var resBody;
bool searching =  false,api_no_limit = false;
String user = null;

Future _getUser(String text) async{
setState(() {
  searching = true;
});
user = text;
_textController.clear();
String url = "https://api.github.com/users/"+text;
  var res = await http
      .get(Uri.encodeFull(url), headers: {"Accept": 
           "application/json"});
  setState(() {
    resBody = json.decode(res.body);
  });
}
Run Code Online (Sandbox Code Playgroud)

spk*_*ten 13

如果你看看以下的实现setState

  void setState(VoidCallback fn) {
    assert(fn != null);
    assert(...);
    final dynamic result = fn() as dynamic;
    assert(...);
    _element.markNeedsBuild();
  }
Run Code Online (Sandbox Code Playgroud)

您会看到它所做的唯一事情是:断言一些事情来帮助您调试它的错误使用,执行回调,并标记元素以便重建它。

因此,从技术上讲,无论您更改 setState 回调内部还是外部的某些变量都没有关系,只要setState被调用即可。

然而,就可读性而言,存在很大差异。重建小部件会影响应用程序的性能,因此您希望尽可能少地这样做。对需要小部件在回调内重建的变量进行所有且仅那些更改,setState可以让人们(包括未来的自己)清楚为什么需要重建。


Gün*_*uer 12

当您更改有状态小部件的状态时,用于setState()导致小部件及其后代的重建。
您不需要setState()在构造函数或initState()小部件中调用,因为build()无论如何都会在之后运行。

也不要setState()在里面调用同步代码build()。您不需要重新运行build()from inside build()

  • 我很确定他的问题是关于“为什么我们不在 setState 回调中计算所有内容?” (8认同)

att*_*ona 9

根据文档

调用setState会通知框架此对象的内部状态已更改,该方式可能会影响此子树中的用户界面,这会导致框架为该State对象安排构建。

因此,如果小部件的状态发生变化必须调用setState以触​​发视图重建,并立即查看新状态所隐含的更改。

无论如何,以下片段都是等效的。

第一种情况(直接形式flutter create <myproject>):

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {

    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }
Run Code Online (Sandbox Code Playgroud)

第二种情况:

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    _counter++;
    setState(() {});
  }
Run Code Online (Sandbox Code Playgroud)

我不知道的原因是,如果第一种情况是常规的使用方式setState,我会说是因为代码的可读性。

  • 问题是,很多人都在问同样的问题,_为什么_第一种方法是约定。该文档说_“通常建议 setState 方法仅用于包装对状态的实际更改,而不是可能与更改相关的任何计算。”_但是如果我的更改是我的大型高清图像怎么办?从 base64 字符串读取?如果图像的读取和转换在此之前完成,我要在“setState()”中放入什么? (5认同)

小智 6

当您需要更改任何小部件在屏幕上显示的值时。例如,应用程序中有一个任务。完成后哪些积分应该添加到“钱包”中。但问题是我们需要刷新应用才能看到“钱包”上的积分。为了解决这个问题,我们在 Button Onpressed() 上使用 Setstate()

例如:

RaisedButton(
 
 onpressed(){
    
   setstate(){
      
     points+10;

   }
 }

)
Run Code Online (Sandbox Code Playgroud)

每次按下按钮时,它都会使用“wallet”变量返回的新值刷新小部件,而无需重新启动整个应用程序。