Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextFormField: setState() or markNeedsBuild() called during build

Tags:

flutter

dart

I'm trying to set first time button as disabled and when user enters amount it gets enabled, button disable works fine but when i enter amount in TextFormField it gives below error.

   I/flutter (29519): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY 
   ╞═══════════════════════════════════════════════════════════
   I/flutter (29519): The following assertion was thrown building 
   TextFormField(dirty, state: _TextFormFieldState#b89da):
   I/flutter (29519): setState() or markNeedsBuild() called during build.
   I/flutter (29519): This HomePage widget cannot be marked as needing to 
   build because the framework is already in the
   I/flutter (29519): process of building widgets. A widget can be marked as 
   needing to be built during the build phase
   I/flutter (29519): only if one of its ancestors is currently building. 
   This exception is allowed because the framework
   I/flutter (29519): builds parent widgets before children, which means a 
   dirty descendant will always be built.
   I/flutter (29519): Otherwise, the framework might not visit this widget 
   during this build phase.
   I/flutter (29519): The widget on which setState() or markNeedsBuild() was 
   called was:

my code:

var _onPressed;
if (isButtonDisabled) {
  _onPressed = () {
    print("Hello");
  };
}

TextFormField code:

child: TextFormField(
  decoration: InputDecoration(
    contentPadding: EdgeInsets.only(
      left: 12.0,
      right: 12.0,
      top: 12.0,
      bottom: 12.0
    ),
    labelText: 'Enter amount',
    hintText: 'Enter amount',
    hintStyle: TextStyle(
      color: Colors.red,
      fontSize: 14.0
    ),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(0.0)
    ),
  ),
  keyboardType: TextInputType.number,
  autovalidate: true,
  validator: (String txt) {
    if (txt.length == 2) {
      setState(() {
        isButtonDisabled = true;
      });
    } else {
      setState(() {
        isButtonDisabled = false;
      });
    }
  }
),       

Button Code:

FlatButton(
  child: Text("Confirm"),
  onPressed: _onPressed,
)                                  
like image 250
Pradnya Bhagat Avatar asked Dec 18 '22 19:12

Pradnya Bhagat


1 Answers

Remove setState from

   if (txt.length == 2){
     setState((){
     isButtonDisabled = true;
     });
   } else {
     setState((){
       isButtonDisabled = false;
      });
     }}),   

to

   if (txt.length == 2){
     isButtonDisabled = true;
   } else {
       isButtonDisabled = false;
   }}),   

You don't need call setState() in code executed directly in build(), only if you pass functions like

onPressed: () {
  // code here is not executed in `build()`, 
  it's just passed to `onPressed` to be executed when the button is tapped
  // therefore here `setState()` is required for state changes 
}

validator: () {...} looks similar, but doesn't update the state of your widget.

like image 74
Günter Zöchbauer Avatar answered Mar 08 '23 05:03

Günter Zöchbauer