Skip to content

Commit

Permalink
Update MaterialStatesController docs for calling setState in a li…
Browse files Browse the repository at this point in the history
…stener (#143453)

fixes [Calling `setState` in a `MaterialStatesController` listener and `MaterialStateController.update` causes Exception](flutter/flutter#138986)

### Description
`MaterialStatesController` listener  calls `setState` during build when `MaterialStatesController.update` listener calls `notifyListeners`.

I tried fixing this issue by putting `notifyListeners` in a post-frame callback. However, this breaks existing customer tests (particularly super editor tests).

A safer approach would be to document that the listener's `setState` call should be in a post-frame callback to delay it and not call this during the build phase triggered by the `MaterialStatesController.update` in the widgets such as InkWell or buttons.
  • Loading branch information
TahaTesser authored Feb 16, 2024
1 parent 8129797 commit a603a17
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/flutter/lib/src/material/material_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,14 @@ class MaterialStatePropertyAll<T> implements MaterialStateProperty<T> {
/// [MaterialState.focused] to its controller. When the widget gains the
/// or loses the focus it will [update] its controller's [value] and
/// notify listeners of the change.
///
/// When calling `setState` in a [MaterialStatesController] listener, use the
/// [SchedulerBinding.addPostFrameCallback] to delay the call to `setState` after
/// the frame has been rendered. It's generally prudent to use the
/// [SchedulerBinding.addPostFrameCallback] because some of the widgets that
/// depend on [MaterialStatesController] may call [update] in their build method.
/// In such cases, listener's that call `setState` - during the build phase - will cause
/// an error.
class MaterialStatesController extends ValueNotifier<Set<MaterialState>> {
/// Creates a MaterialStatesController.
MaterialStatesController([Set<MaterialState>? value]) : super(<MaterialState>{...?value});
Expand Down

0 comments on commit a603a17

Please sign in to comment.