[英]Flutter: What is the need of state management libraries when I can use global variables and use setState instead?
[英]When do I use setState in Flutter?
作為 flutter 的新手,在Flutter
應用程序中使用setState
時對我來說非常困惑。 在下面的代碼中,布爾searching
和 var resBody
在setState
。 我的問題是為什么只在 setState 中searching
和resBody
? 為什么不是其他變量?
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.