[英]When do I use setState in Flutter?
As newbie in flutter it's very confusing for me when use setState
in Flutter
application.作为 flutter 的新手,在
Flutter
应用程序中使用setState
时对我来说非常困惑。 In below code boolean searching
and var resBody
used inside setState
.在下面的代码中,布尔
searching
和 var resBody
在setState
。 My question is why only searching
and resBody
inside setState?我的问题是为什么只在 setState 中
searching
和resBody
? Why not others variable?为什么不是其他变量?
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);
});
}
Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.
调用 setState 通知框架此对象的内部状态已更改,可能会影响此子树中的用户界面,这会导致框架为此 State 对象安排构建。
So if the state of the widget changes you have to call setState
to trigger a rebuild of the view and see immediatly the changes implied by the new state.因此,如果小部件的状态发生变化,您必须调用
setState
来触发视图的重建并立即查看新状态所隐含的更改。
Anyhow the below snippets are equivalent.无论如何,以下片段是等效的。
first case (directly form flutter create <myproject>
):第一种情况(直接形成
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++;
});
}
second case:第二种情况:
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
_counter++;
setState(() {});
}
What I don't know is the reason why and if the first case is the conventional way to use setState
, I would say because of readability of code.我不知道是为什么以及如果第一种情况是使用
setState
的常规方法,我会说是因为代码的可读性。
When you change the state of a stateful widget, use setState()
to cause a rebuild of the widget and it's descendants.当您更改有状态小部件的状态时,请使用
setState()
来重建小部件及其后代。
You don't need to call setState()
in the constructor or initState()
of the widget, because build()
will be run afterwards anyway.您不需要在小部件的构造函数或
initState()
中调用setState()
,因为无论如何都会在之后运行build()
。
Also don't call setState()
in synchronous code inside build()
.也不要在
build()
内的同步代码中调用setState()
build()
。 You shouldn't need to cause a rerun of build()
from within build()
.你不应该需要引起的重播
build()
从内部build()
If you look at the implementation of setState
:如果您查看
setState
的实现:
void setState(VoidCallback fn) {
assert(fn != null);
assert(...);
final dynamic result = fn() as dynamic;
assert(...);
_element.markNeedsBuild();
}
you see that the only things it does are: asserting a few things to help you debug incorrect usage of it, executing the callback, and marking the element so it gets rebuild.你会看到它唯一做的事情是:断言一些事情来帮助你调试它的错误使用,执行回调,并标记元素以使其重建。
So, technically, it doesn't matter if you change some variables inside the setState callback or outside of it, as long as setState
is called.因此,从技术上讲,只要
setState
被调用,在 setState 回调内部或外部更改某些变量都没有关系。
However, for readability there is a big difference.但是,对于可读性,存在很大差异。 Rebuilding widgets has impact on the performance of the app, so you want to do so as little as possible.
重建小部件会影响应用程序的性能,因此您希望尽可能少地这样做。 Making all, and only those, changes to variables that require the widget to rebuild inside the
setState
callback makes it clear to people (including your future self) exactly why a rebuild is needed.对需要小部件在
setState
回调中重建的变量进行所有(且仅这些)更改,可以让人们(包括您未来的自己)清楚为什么需要重建。
When you need to change the value any widget shows on the screen.当您需要更改屏幕上显示的任何小部件的值时。 For example, in the app there was a task.
例如,在应用程序中有一个任务。 After completion of which points should be added to the "wallet".
完成后应将哪些积分添加到“钱包”中。 But the problem is that we need to refresh the app to see points on the "wallet".
但问题是我们需要刷新应用才能看到“钱包”上的积分。 To solve this we use Setstate() on Button Onpressed()
为了解决这个问题,我们在 Button Onpressed() 上使用 Setstate()
For example:例如:
RaisedButton(
onpressed(){
setstate(){
points+10;
}
}
)
Every time the button is pressed it will refresh the widget with the new value returned by the "wallet" variable without the need to restart the entire App.每次按下按钮时,它都会使用“钱包”变量返回的新值刷新小部件,而无需重新启动整个应用程序。
According to the documentations :根据文件:
Generally it is recommended that the
setState
method only be used to wrap the actual changes to the state, not any computation that might be associated with the change.通常建议
setState
方法仅用于包装对状态的实际更改,而不是任何可能与更改相关联的计算。 For example, here a value used by thebuild
function is incremented, and then the change is written to disk, but only the increment is wrapped in thesetState
:例如,这里将
build
函数使用的值递增,然后将更改写入磁盘,但只有递增量包装在setState
:Future<void> _incrementCounter() async { setState(() { _counter++; }); Directory directory = await getApplicationDocumentsDirectory(); final String dirName = directory.path; await File('$dir/counter.txt').writeAsString('$_counter'); }
Whenever you want to update a widget tree (generally with some new data), you call setState
.每当您想要更新小部件树(通常使用一些新数据)时,您都可以调用
setState
。 It can only be used in State
class.它只能在
State
类中使用。 Here's the simple implementation:这是简单的实现:
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()
is only being used with statefulWidget insides flutter. setState()
仅用于 statefulWidget 内部颤动。 setState()
tell the flutter to rebuild the page when something defined inside the setState()
changes. setState()
告诉 flutter 在setState()
定义的某些内容发生更改时重建页面。
NOT: setState()
is a callback function. NOT:
setState()
是一个回调函数。
Text(questions[questionIndex])
Here I want to change the Text according to the given questions array, and on every button click, I want to increase the index by 1.在这里,我想根据给定的问题数组更改文本,并且每次单击按钮时,我都想将索引增加 1。
void answerQuesion() {
setState(() {
questionIndex = questionIndex + 1;
});
print(questionIndex);
}
So, I have to put this index increment inside the setState()
, so that flutter will rebuild the page after every change of questionIndex.因此,我必须将此索引增量放入
setState()
,以便每次更改 questionIndex 后,flutter 都会重建页面。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.