setState documentation (#132090)
Fixes https://github.com/flutter/flutter/issues/12296
This commit is contained in:
parent
eb126ccfc7
commit
1e35d3a6b7
@ -458,8 +458,9 @@ class _SnippetChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const List<String> ignoresDirectives = <String>[
|
static const List<String> ignoresDirectives = <String>[
|
||||||
'// ignore_for_file: duplicate_ignore',
|
|
||||||
'// ignore_for_file: directives_ordering',
|
'// ignore_for_file: directives_ordering',
|
||||||
|
'// ignore_for_file: duplicate_ignore',
|
||||||
|
'// ignore_for_file: no_leading_underscores_for_local_identifiers',
|
||||||
'// ignore_for_file: prefer_final_locals',
|
'// ignore_for_file: prefer_final_locals',
|
||||||
'// ignore_for_file: unnecessary_import',
|
'// ignore_for_file: unnecessary_import',
|
||||||
'// ignore_for_file: unreachable_from_main',
|
'// ignore_for_file: unreachable_from_main',
|
||||||
|
@ -45,6 +45,7 @@ export 'package:flutter/rendering.dart' show RenderBox, RenderObject, debugDumpL
|
|||||||
// late Object? _myState, newValue;
|
// late Object? _myState, newValue;
|
||||||
// int _counter = 0;
|
// int _counter = 0;
|
||||||
// Future<Directory> getApplicationDocumentsDirectory() async => Directory('');
|
// Future<Directory> getApplicationDocumentsDirectory() async => Directory('');
|
||||||
|
// late AnimationController animation;
|
||||||
|
|
||||||
// An annotation used by test_analysis package to verify patterns are followed
|
// An annotation used by test_analysis package to verify patterns are followed
|
||||||
// that allow for tree-shaking of both fields and their initializers. This
|
// that allow for tree-shaking of both fields and their initializers. This
|
||||||
@ -1092,9 +1093,73 @@ abstract class State<T extends StatefulWidget> with Diagnosticable {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// Sometimes, the changed state is in some other object not owned by the
|
||||||
|
/// widget [State], but the widget nonetheless needs to be updated to react to
|
||||||
|
/// the new state. This is especially common with [Listenable]s, such as
|
||||||
|
/// [AnimationController]s.
|
||||||
|
///
|
||||||
|
/// In such cases, it is good practice to leave a comment in the callback
|
||||||
|
/// passed to [setState] that explains what state changed:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// void _update() {
|
||||||
|
/// setState(() { /* The animation changed. */ });
|
||||||
|
/// }
|
||||||
|
/// //...
|
||||||
|
/// animation.addListener(_update);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// It is an error to call this method after the framework calls [dispose].
|
/// It is an error to call this method after the framework calls [dispose].
|
||||||
/// You can determine whether it is legal to call this method by checking
|
/// You can determine whether it is legal to call this method by checking
|
||||||
/// whether the [mounted] property is true.
|
/// whether the [mounted] property is true. That said, it is better practice
|
||||||
|
/// to cancel whatever work might trigger the [setState] rather than merely
|
||||||
|
/// checking for [mounted] before calling [setState], as otherwise CPU cycles
|
||||||
|
/// will be wasted.
|
||||||
|
///
|
||||||
|
/// ## Design discussion
|
||||||
|
///
|
||||||
|
/// The original version of this API was a method called `markNeedsBuild`, for
|
||||||
|
/// consistency with [RenderObject.markNeedsLayout],
|
||||||
|
/// [RenderObject.markNeedsPaint], _et al_.
|
||||||
|
///
|
||||||
|
/// However, early user testing of the Flutter framework revealed that people
|
||||||
|
/// would call `markNeedsBuild()` much more often than necessary. Essentially,
|
||||||
|
/// people used it like a good luck charm, any time they weren't sure if they
|
||||||
|
/// needed to call it, they would call it, just in case.
|
||||||
|
///
|
||||||
|
/// Naturally, this led to performance issues in applications.
|
||||||
|
///
|
||||||
|
/// When the API was changed to take a callback instead, this practice was
|
||||||
|
/// greatly reduced. One hypothesis is that prompting developers to actually
|
||||||
|
/// update their state in a callback caused developers to think more carefully
|
||||||
|
/// about what exactly was being updated, and thus improved their understanding
|
||||||
|
/// of the appropriate times to call the method.
|
||||||
|
///
|
||||||
|
/// In practice, the [setState] method's implementation is trivial: it calls
|
||||||
|
/// the provided callback synchronously, then calls [Element.markNeedsBuild].
|
||||||
|
///
|
||||||
|
/// ## Performance considerations
|
||||||
|
///
|
||||||
|
/// There is minimal _direct_ overhead to calling this function, and as it is
|
||||||
|
/// expected to be called at most once per frame, the overhead is irrelevant
|
||||||
|
/// anyway. Nonetheless, it is best to avoid calling this function redundantly
|
||||||
|
/// (e.g. in a tight loop), as it does involve creating a closure and calling
|
||||||
|
/// it. The method is idempotent, there is no benefit to calling it more than
|
||||||
|
/// once per [State] per frame.
|
||||||
|
///
|
||||||
|
/// The _indirect_ cost of causing this function, however, is high: it causes
|
||||||
|
/// the widget to rebuild, possibly triggering rebuilds for the entire subtree
|
||||||
|
/// rooted at this widget, and further triggering a relayout and repaint of
|
||||||
|
/// the entire corresponding [RenderObject] subtree.
|
||||||
|
///
|
||||||
|
/// For this reason, this method should only be called when the [build] method
|
||||||
|
/// will, as a result of whatever state change was detected, change its result
|
||||||
|
/// meaningfully.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [StatefulWidget], the API documentation for which has a section on
|
||||||
|
/// performance considerations that are relevant here.
|
||||||
@protected
|
@protected
|
||||||
void setState(VoidCallback fn) {
|
void setState(VoidCallback fn) {
|
||||||
assert(() {
|
assert(() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user