Throw FlutterError when calling setState in State constructor (#16759)

* log error when calling setState in constructor
This commit is contained in:
Jonah Williams 2018-04-19 18:00:38 -07:00 committed by GitHub
parent 034a663d33
commit e7cd5d3867
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 0 deletions

View File

@ -1103,6 +1103,15 @@ abstract class State<T extends StatefulWidget> extends Diagnosticable {
'consider breaking the reference to this object during dispose().'
);
}
if (_debugLifecycleState == _StateLifecycle.created && !mounted) {
throw new FlutterError(
'setState() called in constructor: $this\n'
'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;

View File

@ -0,0 +1,34 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
class BadWidget extends StatefulWidget {
@override
State<StatefulWidget> createState() => new BadWidgetState();
}
class BadWidgetState extends State<BadWidget> {
BadWidgetState() {
setState(() {
_count = 1;
});
}
int _count = 0;
@override
Widget build(BuildContext context) {
return new Text(_count.toString());
}
}
void main() {
testWidgets('setState() catches being used inside a constructor', (WidgetTester tester) async {
await tester.pumpWidget(new BadWidget());
expect(tester.takeException(), const isInstanceOf<FlutterError>());
});
}