setState应该在flift小部件中有任何正文[duplicate]

问题描述 投票:1回答:2

我正在查看setState的文档,并指出

通知框架此对象的内部状态为已更改。

我猜文档真的意味着要强调this

通知框架<< [this对象的内部状态已更改。

我尝试使用默认生成的代码尝试使用

empty setState,它能够触发通知。

import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { _counter++; // moved it out of setState setState(() { // _counter++; // instead setting it before setState }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
上面的代码确实可以正常工作,但是我在互联网上发现的所有示例都明确地更改了值或使用setState进行了一些活动,真的有必要吗?
flutter
2个回答
0
投票
是的。

setState中的回调不携带source code中所传达的魔力。它没有被传递下来,并在某些内部生命周期内被调用。

提供的回调将立即被同步调用。它一定不能返回future(回调不能是异步的),因为从那时起,不清楚何时实际设置状态。

@protected void setState(VoidCallback fn) { final dynamic result = fn() as dynamic; _element.markNeedsBuild(); }
没有断言的源代码。

它只是帮助您立即在闭包内部执行代码,然后将其标记为在下一帧中重建。就这样。尽管它可以与空白回调一起使用,但不建议这样做。

这可能与可维护性有关,因为setState内部的所有事物都应改变小部件的状态,而毫不奇怪地明确指出。


0
投票

Short:] >>You can call setState with an empty body.

(但是它会变得更容易阅读,更容易理解体内是否有东西,对吧?)>

较长版本:

] >>Flutter将检查某些情况,例如回调不为null,声明当前小部件的状态,回调不能为异步...Flutter会在标记小部件需要重新构建之前执行setState体内的任何操作。

@protected void setState(VoidCallback fn) { assert(fn != null); assert(() { if (_debugLifecycleState == _StateLifecycle.defunct) { throw FlutterError.fromParts(<DiagnosticsNode>[ ErrorSummary('setState() called after dispose(): $this'), ErrorDescription( 'This error happens if you call setState() on a State object for a widget that ' 'no longer appears in the widget tree (e.g., whose parent widget no longer ' 'includes the widget in its build). This error can occur when code calls ' 'setState() from a timer or an animation callback.' ), ErrorHint( 'The preferred solution is ' 'to cancel the timer or stop listening to the animation in the dispose() ' 'callback. Another solution is to check the "mounted" property of this ' 'object before calling setState() to ensure the object is still in the ' 'tree.' ), ErrorHint( 'This error might indicate a memory leak if setState() is being called ' 'because another object is retaining a reference to this State object ' 'after it has been removed from the tree. To avoid memory leaks, ' 'consider breaking the reference to this object during dispose().' ), ]); } if (_debugLifecycleState == _StateLifecycle.created && !mounted) { throw FlutterError.fromParts(<DiagnosticsNode>[ ErrorSummary('setState() called in constructor: $this'), ErrorHint( 'This happens when you call setState() on a State object for a widget that ' 'hasn\'t been inserted into the widget tree yet. It is not necessary to call ' 'setState() in the constructor, since the state is already assumed to be dirty ' 'when it is initially created.' ), ]); } return true; }()); final dynamic result = fn() as dynamic; assert(() { if (result is Future) { throw FlutterError.fromParts(<DiagnosticsNode>[ ErrorSummary('setState() callback argument returned a Future.'), ErrorDescription( 'The setState() method on $this was called with a closure or method that ' 'returned a Future. Maybe it is marked as "async".' ), ErrorHint( 'Instead of performing asynchronous work inside a call to setState(), first ' 'execute the work (without updating the widget state), and then synchronously ' 'update the state inside a call to setState().' ), ]); } // We ignore other types of return values so that you can do things like: // setState(() => x = 3); return true; }()); _element.markNeedsBuild(); }

© www.soinside.com 2019 - 2024. All rights reserved.