Skip to content

Stop passing State objects between widgets in LayoutExplorer - #10006

Open
srawlins wants to merge 1 commit into
flutter:masterfrom
srawlins:issue-2701
Open

srawlins wants to merge 1 commit into
flutter:masterfrom
srawlins:issue-2701

Conversation

@srawlins

@srawlins srawlins commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Replaces passing FlexLayoutExplorerWidgetState down to VisualizeFlexChildren and FlexChildVisualizer with FlexLayoutExplorerScope, an InheritedWidget.

FlexLayoutExplorerScope provides descendants with scoped access to rootProperties, the entrance animation (entranceController and entranceCurve), and the necessary interaction callbacks (markAsDirty, onTap, and onDoubleTap). This eliminates passing mutable State objects down the widget tree while avoiding prop drilling and preserving all existing layout visualizer behaviors.

Fixes #2701

build.yaml badge

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the flex layout explorer by introducing FlexLayoutExplorerScope, an InheritedWidget used to share properties and callbacks down the widget tree. This successfully removes the need to pass the state object directly to child widgets. The review feedback recommends adding defensive null checks for the nullable objectGroup in FlexChildVisualizer to avoid potential runtime crashes from using the null-assertion operator.

Replace passing FlexLayoutExplorerWidgetState to VisualizeFlexChildren
and FlexChildVisualizer with _FlexLayoutExplorerScope, an InheritedWidget
providing rootProperties, animation controllers, and mutation/selection
callbacks.

Fixes flutter#2701
@srawlins

Copy link
Copy Markdown
Contributor Author

Hi @hannah-hyj , I added you as a reviewer as I think this is a pure "flutter best practices" PR with nothing to do with DevTools business logic. I'd love your input.

@kenzieschmoll kenzieschmoll left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why an InheritedWidget here? A few reasons I'd avoid it:

  • The drilling is one hop. VisualizeFlexChildren is the only widget between FlexLayoutExplorerWidgetState and FlexChildVisualizer, and it already forwards five other params.
  • No rebuild-scoping benefit. _buildLayout runs inside AnimatedBuilder(animation: changeController)LayoutBuilder, so every consumer is rebuilt top-down anyway. updateShouldNotify can't trigger a rebuild that isn't already happening.
  • Compile-time guarantee becomes runtime. required this.state was enforced by the compiler; _of(context) is an assert + !. It also means FlexChildVisualizer can't be built or widget-tested without a scope wrapper. Note this replaces the TODO(polina-c, jacob314): consider refactoring to remove ! with a new !.

#2701 is about what we pass, not how. onTap, onDoubleTap, markAsDirty, and properties are app logic that shouldn't be on a State — that's the root cause. These belong on InspectorController, or on a layout-explorer sub-controller that InspectorController owns and disposes. InspectorController already holds _layoutGroups for this feature and LayoutExplorerWidgetState already has widget.inspectorController, so children can reach it without any new plumbing. That removes the state-passing and makes the logic unit-testable — neither of which the scope gets us. It also drops the markAsDirty threading this PR adds through _buildContent → the two dropdown builders → _onChangeFlexFactor/_onChangeFlexFit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stop passing State objects between widgets in the LayoutExplorer

2 participants