Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
bcc8f083
Unverified
Commit
bcc8f083
authored
Jun 07, 2021
by
Dan Field
Committed by
GitHub
Jun 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Forbid calling findRenderObject on an unmounted element (#83962)
parent
0100285e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
50 additions
and
2 deletions
+50
-2
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+21
-2
widget_inspector.dart
packages/flutter/lib/src/widgets/widget_inspector.dart
+5
-0
framework_test.dart
packages/flutter/test/widgets/framework_test.dart
+24
-0
No files found.
packages/flutter/lib/src/widgets/framework.dart
View file @
bcc8f083
...
@@ -2056,7 +2056,8 @@ abstract class BuildContext {
...
@@ -2056,7 +2056,8 @@ abstract class BuildContext {
/// This method will only return a valid result after the build phase is
/// This method will only return a valid result after the build phase is
/// complete. It is therefore not valid to call this from a build method.
/// complete. It is therefore not valid to call this from a build method.
/// It should only be called from interaction event handlers (e.g.
/// It should only be called from interaction event handlers (e.g.
/// gesture callbacks) or layout or paint callbacks.
/// gesture callbacks) or layout or paint callbacks. It is also not valid to
/// call if [State.mounted] returns false.
///
///
/// If the render object is a [RenderBox], which is the common case, then the
/// If the render object is a [RenderBox], which is the common case, then the
/// size of the render object can be obtained from the [size] getter. This is
/// size of the render object can be obtained from the [size] getter. This is
...
@@ -3864,7 +3865,25 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
...
@@ -3864,7 +3865,25 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
}
}
@override
@override
RenderObject
?
findRenderObject
()
=>
renderObject
;
RenderObject
?
findRenderObject
()
{
assert
(()
{
if
(
_lifecycleState
!=
_ElementLifecycle
.
active
)
{
throw
FlutterError
.
fromParts
(<
DiagnosticsNode
>[
ErrorSummary
(
'Cannot get renderObject of inactive element.'
),
ErrorDescription
(
'In order for an element to have a valid renderObject, it must be '
'active, which means it is part of the tree.
\n
'
'Instead, this element is in the
$_lifecycleState
state.
\n
'
'If you called this method from a State object, consider guarding '
'it with State.mounted.'
,
),
describeElement
(
'The findRenderObject() method was called for the following element'
),
]);
}
return
true
;
}());
return
renderObject
;
}
@override
@override
Size
?
get
size
{
Size
?
get
size
{
...
...
packages/flutter/lib/src/widgets/widget_inspector.dart
View file @
bcc8f083
...
@@ -2455,6 +2455,11 @@ class InspectorSelection {
...
@@ -2455,6 +2455,11 @@ class InspectorSelection {
Element
?
_currentElement
;
Element
?
_currentElement
;
set
currentElement
(
Element
?
element
)
{
set
currentElement
(
Element
?
element
)
{
if
(
element
?.
debugIsDefunct
==
true
)
{
_currentElement
=
null
;
_current
=
null
;
return
;
}
if
(
currentElement
!=
element
)
{
if
(
currentElement
!=
element
)
{
_currentElement
=
element
;
_currentElement
=
element
;
_current
=
element
!.
findRenderObject
();
_current
=
element
!.
findRenderObject
();
...
...
packages/flutter/test/widgets/framework_test.dart
View file @
bcc8f083
...
@@ -1619,6 +1619,30 @@ void main() {
...
@@ -1619,6 +1619,30 @@ void main() {
await
pumpWidget
(
Container
());
await
pumpWidget
(
Container
());
expect
(
states
,
<
String
>[
'deactivate'
,
'dispose'
]);
expect
(
states
,
<
String
>[
'deactivate'
,
'dispose'
]);
});
});
testWidgets
(
'Getting the render object of an unmounted element throws'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
_StatefulLeaf
());
final
StatefulElement
element
=
tester
.
element
<
StatefulElement
>(
find
.
byType
(
_StatefulLeaf
));
expect
(
element
.
state
,
isA
<
State
<
_StatefulLeaf
>>());
expect
(
element
.
widget
,
isA
<
_StatefulLeaf
>());
// Replace the widget tree to unmount the element.
await
tester
.
pumpWidget
(
Container
());
expect
(
()
=>
element
.
findRenderObject
(),
throwsA
(
isA
<
FlutterError
>().
having
(
(
FlutterError
error
)
=>
error
.
message
,
'message'
,
equalsIgnoringHashCodes
(
'''
Cannot get renderObject of inactive element.
In order for an element to have a valid renderObject, it must be active, which means it is part of the tree.
Instead, this element is in the _ElementLifecycle.defunct state.
If you called this method from a State object, consider guarding it with State.mounted.
The findRenderObject() method was called for the following element:
StatefulElement#00000(DEFUNCT)'''
),
)),
);
});
}
}
class
_WidgetWithNoVisitChildren
extends
StatelessWidget
{
class
_WidgetWithNoVisitChildren
extends
StatelessWidget
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment