Search code examples
fluttersetstate

Does setState() have any limitations with regard to updating UI


I am trying to update a TextField to show an error text until the email is validated by an external validators package. However, the UI does not update even though I am calling the setState from within the build method. I tried debugging by using print statements(screenshot attached) and the behavior is as expected. Why then does the UI not update showing the TextField with the error text below it if I try to pass in an updated TextField UI in the setState() ?

Code that does work

Code that does work

Code that does not work

                    child:  TextField(
                      decoration: InputDecoration(
                          hintText: "Enter Email Id",
                          border: OutlineInputBorder()),
                      onChanged: (String value) {
                        emailId = value;
                        setState(() {
                          isEmail(value)
                              ? print("true")
                              : TextField(
                                  decoration: InputDecoration(
                                      errorText: "Enter valid email"),
                                );
                        });
                      },

Solution

  • Your code doesn't work because you're not changing the state of the parent widget inside its onChanged: property. You are creating a new widget on set state

    child: TextField( //parent
          decoration: InputDecoration(
          hintText: "Enter Email Id",
          border: OutlineInputBorder()),
                  onChanged: (String value) {
                  emailId = value;
                  setState(() {
                     isEmail(value)
                        ? print("true")
                        : TextField( //this is not the same widget.
                            decoration: InputDecoration(
                             errorText: "Enter valid email"),
                         );
                        });
                      },
    

    You can solve this by declaring String invalidEmailError and set this on errorText property of TextField. Later update this this string to get the desired result.

    TextField(
          decoration: InputDecoration(
          hintText: "Enter Email Id",
              errorText: invalidEmailError,
              border: OutlineInputBorder()),
              onChanged: (String value) {
              emailId = value;
            setState(() {
                isEmail(value)
                    ? invalidEmailError = null
                    : invalidEmailError = "Enter valid email";
            });
          },
          )