Skip to content

Converted GuessInput to a StatefulWidget in Stateful widgets tutorial - #13653

Open
MuthuGCodes wants to merge 9 commits into
flutter:mainfrom
MuthuGCodes:mg-GuessInput-issue
Open

Converted GuessInput to a StatefulWidget in Stateful widgets tutorial#13653
MuthuGCodes wants to merge 9 commits into
flutter:mainfrom
MuthuGCodes:mg-GuessInput-issue

Conversation

@MuthuGCodes

@MuthuGCodes MuthuGCodes commented Jul 31, 2026

Copy link
Copy Markdown

Rebuilding GamePage (after converting it to StatefulWidget) recreates GuessInput (which is currently a StatelessWidget), resetting its internal FocusNode and TextEditingController and breaking focus behavior. The fix is to convert GuessInput to a StatefulWidget in the "Stateful widgets" tutorial step and the example code.

Fixes #13392

@flutter-website-bot

flutter-website-bot commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Staged preview of the updated docs.flutter.dev site (updated for commit 8150ada):

https://flutter-docs-prod--docs-pr13653-mg-guessinput-issue-3th19sc7.web.app

@flutter-website-bot

flutter-website-bot commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Staged preview of the updated flutter.dev site (updated for commit 8150ada):

https://flutter-dev-230821--www-pr13653-mg-guessinput-issue-hk3zmet1.web.app

@lamek lamek 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.

A few things to fix.

Comment thread workspace.code-workspace Outdated
@@ -0,0 +1,8 @@
{

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.

This file is local to your IDE. You can remove it.

1. Implement `dispose()` to clean up `_textEditingController` and `_focusNode`.

Your modified `GuessInput` widget should look like this:

@lamek lamek Aug 3, 2026

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.

For code excerpts in the tutorial we follow these steps:

  1. Write the updated code into the corresponding /examples/FWE/lib file.
  2. Add a tag like the following: <?code-excerpt "fwe/birdle/lib/step5_main.dart (GuessInput)"?>
  3. Run the following command: dart run dash_site --site=docs refresh-excerpts

Following this flow will ensure the code snippets in our .MD files are always up to date with what is in the /examples dir.

@parlough
parlough requested review from lamek and parlough August 13, 2026 15:56
@MuthuGCodes
MuthuGCodes marked this pull request as ready for review August 13, 2026 16:10
@MuthuGCodes
MuthuGCodes requested review from a team and sfshaza2 as code owners August 13, 2026 16:10

@MuthuGCodes MuthuGCodes left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Incorporated review comments

@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 converts the GuessInput widget from a StatelessWidget to a StatefulWidget in the Birdle example to properly manage the lifecycles of TextEditingController and FocusNode, including their disposal. It also updates the tutorial documentation to explain this transition. Feedback was provided to correct a conceptual explanation in the documentation regarding Flutter's widget recreation lifecycle, clarifying that controllers persist because they are moved to the persistent State object rather than being recreated with the widget instance.

Comment on lines +219 to +223
Because `GuessInput` was originally created as a `StatelessWidget`,
every rebuild creates a new `GuessInput` instance,
along with a new `TextEditingController` and `FocusNode`.
This causes the text input field to lose focus after submitting a guess
and leaves unused controllers without proper disposal.

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.

medium

The explanation states that a new GuessInput instance is created on every rebuild because it was a StatelessWidget. However, in Flutter, widget instances are immutable and are recreated on almost every rebuild regardless of whether they are stateful or stateless.

The actual issue is that the TextEditingController and FocusNode were declared as fields of the GuessInput widget class itself. Because the widget is recreated on every parent rebuild, these controllers were also re-instantiated, causing the loss of focus/state and memory leaks.

By converting to a StatefulWidget, these controllers are moved to the persistent State object (_GuessInputState), which survives widget recreation.

Consider clarifying this distinction to help learners better understand Flutter's widget vs. state lifecycle.

Suggested change
Because `GuessInput` was originally created as a `StatelessWidget`,
every rebuild creates a new `GuessInput` instance,
along with a new `TextEditingController` and `FocusNode`.
This causes the text input field to lose focus after submitting a guess
and leaves unused controllers without proper disposal.
Because `GuessInput` was originally created as a `StatelessWidget`,
its `TextEditingController` and `FocusNode` were stored directly in the widget class.
Since a new widget instance is created on every rebuild, these controllers
were recreated each time, causing the text input field to lose focus
and leaving unused controllers without proper disposal.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GuessInput class should be a StatelfulWidget

3 participants