Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Proposal] Add a text parameter to TextField and TextFormField to update their values #167983

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

Open
feinstein opened this issue Apr 29, 2025 · 11 comments
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter f: material design flutter/packages/flutter/material repository. P3 Issues that are less important to the Flutter project team-text-input Owned by Text Input team triaged-text-input Triaged by Text Input team

Comments

@feinstein
Copy link
Contributor

feinstein commented Apr 29, 2025

Use case

The current TextField and TextFormField APIs are almost reactive, but unfortunately we still need to deal with a TextEditingController in most cases, which makes it still an imperative API.

Most Flutter widgets come with a pure reactive API, such as the Switch API:

Switch(
  value: isOn,
  onChanged: (bool value) {
    setState(() {
      isOn = value;
    });
  },
);

This way the widget informs that a value changed, and we can independently control the widget state by setting it's value. This is excellent for integrating Flutter widgets with State Managers and other advanced logic that can react to changes on the fly.

The TextField on the other hand can only do this read/write cycle with a very cumbersome and clunky API:

final _controller = TextEditingController();

// ....

void dispose() {
  _controller.dispose();
  super.dispose();
}

// ....

if (state.text != _controller.text) {
  _controller.text = state.text;
}

TextField(
  controller: _controller,
  onChanged: validateAndUpdateText
)

What really bothers me is that the TextField API is almost there. It already has a onChanged callback, it just lacks a text parameter to set it's value.

Proposal

I propose we add a text parameter in both the TextField and TextFormField, we need to also add an assert to validate if both text and controller were defined at the same time, as this isn't a valid option, the developer needs to choose between one or the other (many widgets have this pattern already).

If controller is null, then internally a TextEditingController is created and disposed (I think this is already the case). When didUpdateWidget shows that the new value of text is different than the old value of text, it just updates the controller.

I understand that this won't cover all the possible cases that a TextEditingController covers, but still this small change will improve developer experience by a big margin, removing lots and lots of boilerplate from our apps.

I think this also aligns with the current strategy of refining Flutter and improving developer experience.

@delfme
Copy link

delfme commented Apr 29, 2025

This approach introduces limitations for more advanced TextField use cases. If implemented, it might be provided as an optional feature for a basic scenario.

@feinstein
Copy link
Contributor Author

What limitations? I am not restricting the API, just expanding it. You can still use a controller, as I said and explained how an assert would work to validate the fields, hence as controller is still there.

@maheshj01 maheshj01 added the in triage Presently being triaged by the triage team label Apr 29, 2025
@maheshj01
Copy link
Member

I am labelling this as a proposal to add text/value parameter to textfield/textformfield

@maheshj01 maheshj01 added c: new feature Nothing broken; request for a new capability f: material design flutter/packages/flutter/material repository. c: proposal A detailed proposal for a change to Flutter team-text-input Owned by Text Input team and removed in triage Presently being triaged by the triage team labels Apr 29, 2025
@maheshj01 maheshj01 changed the title TextField and TextFormField should have a more reactive API [Proposal] AddTextField and TextFormField a text parameter to update its value Apr 29, 2025
@feinstein feinstein changed the title [Proposal] AddTextField and TextFormField a text parameter to update its value [Proposal] Add a text parameter to TextField and TextFormField to update their values Apr 30, 2025
@iamdipanshusingh
Copy link
Contributor

@maheshj01 can you please assign this to me? I can look into this

@delfme
Copy link

delfme commented May 1, 2025

I don't get this change, there is onChanged: onTextChanged callback. If custom state handling is needed, it usually require large flexibility and onChanged is the way to go. I don't see the boilerplate.

@maheshj01
Copy link
Member

maheshj01 commented May 1, 2025

@iamdipanshusingh Please wait until the secondary triage takes a look at this issue and this is prioritized. So that we know this is something flutter team would be interested to work on in the near future.

@feinstein
Copy link
Contributor Author

I don't get this change, there is onChanged: onTextChanged callback. If custom state handling is needed, it usually require large flexibility and onChanged is the way to go. I don't see the boilerplate.

Most of the Flutter widgets work in a reactive manner where they inform they changed and they accept a value. By changing the value in the widget's constructor, the widget reacts.

TextField only does half of this, it only informs change. It can't be updated in a declarative manner, it can't react to change, unless we use the controller in an imperative manner, not declarative.

Thus, if my state manager (e.g. Bloc) has a new state, and I have to update a form with 10 TextFields, then I need to create 10 TextEditingControllers, their variables, initialise them, and not forget to dispose them, and set them when the state changes. That's a lot of extra boilerplate if you ever had to deal with forms and values coming from other sources.

The TextEditingController has its benefits, it allows us to control lots of things and also get notified of changes, but for the vast majority of cases we only want to set the text and get change notifications, and having this at the widget level will simplify these flows a lot.

@delfme
Copy link

delfme commented May 1, 2025

Got it. Actually it would be useful in that specific case πŸ‘

@justinmc justinmc added P3 Issues that are less important to the Flutter project triaged-text-input Triaged by Text Input team labels May 1, 2025
@justinmc
Copy link
Contributor

justinmc commented May 1, 2025

I've wanted to do this kind of thing for so long. This was the very first quirk that bugged me about Flutter when I started using it in 2018. Coming from React at the time, I much preferred the declarative approach. Since then I have been secretly hoping to find a good reason to make it declarative or at least find some clear counterexample to show that we shouldn't.

First hurdle: The parameter should probably be textEditingValue instead of text so that it supports selection and composing (see TextEditingValue). But unfortunately onChanged is called with a String instead of a TextEditingValue. Maybe we should also add an onChangedValue parameter or something.

Then we'd have to make sure that this approach generally works with all of our existing text input features. For example, TextInputFormatter would be one to check. There's probably a lot of other stuff to worry about.

The first step should probably be to just try it out. Add textEditingValue and onChangedValue to EditableText and open a draft PR and see how it works.

If we can get it to work with everything and the API is not too confusing being alongside of TextEditingController, then I think I would approve that πŸ‘

@feinstein
Copy link
Contributor Author

@justinmc good to hear.

This was honestly my first line if thought, but I also wasn't sure if this change wouldn't be too big, and that's why I said that just adding the option for text won't be the perfect solution but would already solve the vast majority of cases we need.

So IMO I agree with your plan, but if at the end you discover that it can't work, than I wouldn't scrap this, I would instead add the option to only set the text and get a solution that's not perfect, but still a lot more helpful than having nothing.

@iamdipanshusingh
Copy link
Contributor

I created this initial draft. I might scrape it though πŸ˜… as I think @justinmc's proposal seems to cover all the editable texts. Will have to see how TextEditingValue works.

In my case, I modified how the local controller is being created, and on didUpdateWidget I'm disposing the previous controller, and then assigning a new one, which is quite a dirty work, but works :)

Screen.Recording.2025-05-02.at.11.56.35.AM.mov

Example app:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                TextField(text: 'initial text $counter'),
                FilledButton(
                  onPressed: () {
                    setState(() {
                      counter++;
                    });
                  },
                  child: Text("increment!"),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: new feature Nothing broken; request for a new capability c: proposal A detailed proposal for a change to Flutter f: material design flutter/packages/flutter/material repository. P3 Issues that are less important to the Flutter project team-text-input Owned by Text Input team triaged-text-input Triaged by Text Input team
Projects
None yet
Development

No branches or pull requests

5 participants