簡體   English   中英

我什么時候在 Flutter 中使用 setState?

[英]When do I use setState in Flutter?

作為 flutter 的新手,在Flutter應用程序中使用setState時對我來說非常困惑。 在下面的代碼中,布爾searching和 var resBodysetState 我的問題是為什么只在 setState 中searchingresBody 為什么不是其他變量?

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);
  });
}

根據文檔

調用 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++;
    });
  }

第二種情況:

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

  void _incrementCounter() {
    _counter++;
    setState(() {});
  }

我不知道是為什么以及如果第一種情況是使用setState的常規方法,我會說是因為代碼的可讀性。

當您更改有狀態小部件的狀態時,請使用setState()來重建小部件及其后代。
您不需要在小部件的構造函數或initState()中調用setState() ,因為無論如何都會在之后運行build()

也不要在build()內的同步代碼中調用setState() build() 你不應該需要引起的重播build()從內部build()

如果您查看setState的實現:

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

你會看到它唯一做的事情是:斷言一些事情來幫助你調試它的錯誤使用,執行回調,並標記元素以使其重建。

因此,從技術上講,只要setState被調用,在 setState 回調內部或外部更改某些變量都沒有關系。

但是,對於可讀性,存在很大差異。 重建小部件會影響應用程序的性能,因此您希望盡可能少地這樣做。 對需要小部件在setState回調中重建的變量進行所有(且僅這些)更改,可以讓人們(包括您未來的自己)清楚為什么需要重建。

當您需要更改屏幕上顯示的任何小部件的值時。 例如,在應用程序中有一個任務。 完成后應將哪些積分添加到“錢包”中。 但問題是我們需要刷新應用才能看到“錢包”上的積分。 為了解決這個問題,我們在 Button Onpressed() 上使用 Setstate()

例如:

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

   }
 }

)

每次按下按鈕時,它都會使用“錢包”變量返回的新值刷新小部件,而無需重新啟動整個應用程序。

根據文件

通常建議setState方法僅用於包裝對狀態的實際更改,而不是任何可能與更改相關聯的計算。 例如,這里將build函數使用的值遞增,然后將更改寫入磁盤,但只有遞增量包裝在setState

 Future<void> _incrementCounter() async { setState(() { _counter++; }); Directory directory = await getApplicationDocumentsDirectory(); final String dirName = directory.path; await File('$dir/counter.txt').writeAsString('$_counter'); }

每當您想要更新小部件樹(通常使用一些新數據)時,您都可以調用setState 它只能在State類中使用。 這是簡單的實現:

class _MyPageState extends State<MyPage> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          onPressed: () => setState(() => _count++),
          child: Text('Count = $_count'),
        ),
      ),
    );
  }
}

setState()僅用於 statefulWidget 內部顫動。 setState()告訴 flutter 在setState()定義的某些內容發生更改時重建頁面。

NOT: setState()是一個回調函數。

Text(questions[questionIndex])

在這里,我想根據給定的問題數組更改文本,並且每次單擊按鈕時,我都想將索引增加 1。

void answerQuesion() {
    setState(() {
      questionIndex = questionIndex + 1;
    });
    print(questionIndex);
  }

因此,我必須將此索引增量放入setState() ,以便每次更改 questionIndex 后,flutter 都會重建頁面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM