i can't call setState() method in stf Widget

i try to save value in EMAIL variable with onChanged by used setState but the setState function not defined. i can’t call it .
MyTextField is statefulWidget. what is problem i don’t know .is problem related with Widget class (_buildAllTextFormField)? or what i’m beginner can anyone help me please?

    import 'package:ecommernce_application/screens/signup.dart';
    import 'package:flutter/material.dart';
    
    import '../widgets/move_to_sign_or_login_screen.dart';
    import '../widgets/sign_login_button.dart';
    import '../widgets/text_field.dart';
    
    class Login extends StatefulWidget {
      const Login({Key? key}) : super(key: key);
      @override
      State<Login> createState() => _LoginState();
    }
    final _formKey = GlobalKey<FormState>();
    bool obscureText = true;
    // for validate Email
    String pEmail = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
    RegExp regExp = RegExp(pEmail);
    void validate(){
      final FormState? form = _formKey.currentState;
      if(form!.validate())
        { debugPrint('Yes'); }
      else { debugPrint('No'); }
    }
    String EMAIL='';
    
    Widget _buildAllTextFormField(BuildContext context){
      return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            padding: const EdgeInsets.only(top: 100),
            width: double.infinity,
            height: 240,
            alignment: Alignment.center,
            child: const Text('Login',style: TextStyle(fontSize: 40,),),
          ),
          const SizedBox(height: 10,),
          Form(
            key: _formKey,
            autovalidateMode: AutovalidateMode.always,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const SizedBox(height: 10,),
                MyTextField(
                  onChanged:(v){
                    ///////////////cant call setState The function 'setState' isn't defined
                    //setState((){});
    
                  },
                  controller: email,
                  validator: (String? value) {
                    if(value == null || value.trim().isEmpty) {
                      return 'Please enter your email address';
                    } // Check if the entered email has the right format
                    if (!regExp.hasMatch(value)) {
                      return 'Please enter a valid email address';
                    } // Return null if the entered email is valid
                    return null;
                  },
                  name: 'Email',),
                const SizedBox(height: 10,),
                MyTextField(
                  onChanged: (value){
    
                  },
                    controller: password,
                    name: 'Password',
                    validator: (value){
                      if (value == null || value.trim().isEmpty) {
                        return 'This field is required';
                      }
                      if (value.trim().length < 8) {
                        return 'Password must be at least 8 characters in length';
                      } // Return null if the entered password is valid
                      return null;
                    }),
                const SizedBox(height: 10,),
    
                _buildBottomPart(context),
              ],
            ),
          ),
        ],
      );
    }
    Widget _buildBottomPart(BuildContext context){
      return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          SignLoginButton(
            name: 'Login',
            onPressed:() { validate(); } ,
            color: Colors.grey,
          ),
          const SizedBox( height: 10, ),
          Padding(
            padding: const EdgeInsets.only( left:8.0 ),
            child:MoveToScreen(
              text1:'I Have Noy Account',
              text2:'SignUp',
              onTap: () {
                Navigator.of(context).pushReplacement ( MaterialPageRoute(builder: (context) => const SignUP() ) );
              },
            ),
          ),
        ],
      );
    }
    final TextEditingController email = TextEditingController();
    final TextEditingController password = TextEditingController();
    class _LoginState extends State<Login> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: SafeArea(
            child: SingleChildScrollView(
              child:TextField(
                onChanged: (v){
                   setState(() {
    
                   });
    
                },
              ),
              // _buildAllTextFormField(context),
            ),
          ),
        );
      }

    

  

MyTextField

import 'package:flutter/material.dart';
            class MyTextField extends StatefulWidget {
              final TextEditingController controller;
              final String name;
              final ValueChanged<String> onChanged;
              final FormFieldValidator<String>  validator;
              const MyTextField({Key? key ,required this.onChanged,required this.controller, required this.name, required this.validator,}) : super(key: key);
              @override
              State<MyTextField> createState() => _MyTextFieldState();
            }
            class _MyTextFieldState extends State<MyTextField> {
              @override
              Widget build(BuildContext context) {
                return SizedBox(
                  width: 400,
                  height: 50,
                  child:  TextFormField(
                    controller: widget.controller,
                    validator: widget.validator,
                    onChanged: widget.onChanged,
                    decoration: InputDecoration(
                        labelText: widget.name,
                        border: const OutlineInputBorder(),
                    ),
                  ),
                );
              }
            }
    
     

PasswordTextField

import 'package:flutter/material.dart';
class PasswordTextField extends StatefulWidget {
  final TextEditingController controller;
  final String name;
  final FormFieldValidator<String>  validator;
  //final ValueChanged<String> onChange;

  const PasswordTextField({Key? key, required this.controller, required this.name, required this.validator}) : super(key: key);

  @override
  State<PasswordTextField> createState() => _PasswordTextFieldState();
}
class _PasswordTextFieldState extends State<PasswordTextField> {
  bool _obscureText = true ;
  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: 400,
      height: 50,
      child:  TextFormField(
        obscureText: _obscureText,
        validator: widget.validator,
        //onChanged: widget.onChange,
        controller: widget.controller,
        decoration: InputDecoration(
          suffixIcon: GestureDetector(
            onTap: (){
              setState(() {
                _obscureText =!_obscureText;
              });
              FocusScope.of(context).unfocus();
              },
            child: Icon( _obscureText == true ? Icons.visibility : Icons.visibility_off,color: Colors.black,),),
          labelText: widget.name,
          border: const OutlineInputBorder(),

        ),
      ),
    );
  }
}

>Solution :

You can do it in this way:

Widget _buildAllTextFormField(BuildContext context, Function() changeCallback){…}

then replace:
_buildAllTextFormField(context)
with
_buildAllTextFormField(context, () => setState((){}))

and then replace:

onChanged:(v){
                ///////////////cant call setState The function 'setState' isn't defined
                //setState((){});

              },

with:

onChanged:(v){
                changeCallback.call();

              },

Leave a Reply