Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Container's child state loss. #163419

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ksokolovskyi
Copy link
Contributor

@ksokolovskyi ksokolovskyi commented Feb 16, 2025

Fixes #161698

Description

  • Updates Container widget to be Stateful and use GlobalKey to preserve the child's state
  • Replaces some occurrences of Container in framework_test.dart with custom _Wrapper widget to retain tests readability. Without this change, we would have to check for KeyedSubtree-[GlobalKey#00000] in tests, instead of Container-[<1>] which decreases readability.
  • Replace Container with SizedBox in lookup_boundary_test.dart, because the test didn't expect the additional KeyedSubtree widget inside the Container.
  • Replaces Container with KeyedSubtree in packages/flutter_test/lib/src/binding.dart. This is because using the Container in TestWidgetsFlutterBinding._runTestBody introduces two additional GlobalKey which affect existing GlobalKey tests.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels. labels Feb 16, 2025
@ksokolovskyi
Copy link
Contributor Author

There is one failing test in flutter/packages/rfw package: https://github.com/flutter/packages/blob/8542af3ddbe4a3fd353b31b28f5fb04065097b3b/packages/rfw/test/runtime_test.dart#L894C15-L894C41

This test tries to get the element of the Container widget pumped by the TestWidgetsFlutterBinding._runTestBody function. This PR replaces that Container with KeyedSubtree (https://github.com/flutter/flutter/pull/163419/files#diff-d34dbaacc51359fa05706c29bf6f9defc134c57d31b2d84313b1bbcc54bd2773L1052) which breaks the test.

Could you please advise what to do in this case?

@justinmc
Copy link
Contributor

@LongCatIsLooong FYI I think we were discussing this problem before you went on leave, see #161698.

@flutter-dashboard
Copy link

This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@Piinks
Copy link
Contributor

Piinks commented Mar 11, 2025

Hey from triage, @LongCatIsLooong and @ksokolovskyi , what is the status of this PR?

@ksokolovskyi ksokolovskyi force-pushed the fix-container-child-state-loss branch from 99b8473 to 9fc1456 Compare March 12, 2025 06:52
@ksokolovskyi
Copy link
Contributor Author

Hi @Piinks. From my side, the PR is ready for review, but I am unsure how to proceed with one failing test in the flutter/packages/rfw package. I described the issue in a comment above.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this PR will require a lot of work to prove this is a valid solution that is not negatively affecting performance, but I appreciate you taking on such a difficult and fundamental problem @ksokolovskyi!

This is the failing rfw test. Can you see if it's something trivial that can be updated? It's probably just depending on Container producing a ColoredBox even when not given a color. https://github.com/flutter/packages/blob/ff7724c18a803542fc709f942c3bf1cecf7e4864/packages/rfw/test/runtime_test.dart#L894

@@ -243,7 +243,7 @@ class DecoratedBox extends SingleChildRenderObjectWidget {
/// [InkResponse] and [InkWell] splashes to paint over them.
/// * Cookbook: [Animate the properties of a container](https://docs.flutter.dev/cookbook/animation/animated-container)
/// * The [catalog of layout widgets](https://docs.flutter.dev/ui/widgets/layout).
class Container extends StatelessWidget {
class Container extends StatefulWidget {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder what the performance implications are about changing this to a stateful widget since Container is used all over the place.

}

class _ContainerState extends State<Container> {
final GlobalKey _childGlobalKey = GlobalKey();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also might be a performance concern. Somewhat related: #161698 (comment)


if (child == null && (constraints == null || !constraints!.isTight)) {
if (current != null) {
current = KeyedSubtree(key: _childGlobalKey, child: current);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chunhtai I think you and I talked about solving this problem with a KeyedSubtree before and decided against it, do you remember the details at all?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: tests "flutter test", flutter_test, or one of our tests framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Container can lose its child's state
3 participants