Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
553 views
in Technique[技术] by (71.8m points)

dart - Flutter : error is Looking up a deactivated widget's ancestor is unsafe

So I am trying to log in using NodeJS in my flutter app, and I am able to log in but when I try to add a circular progress indicator while waiting for backend process to finish when user taps on login button by setting state like,

setState(() {
     validate = true;
      isLoading = true;       
      });

And then I do after successfully logging in,

setState(() {
    validate = true;
    isLoading = false;
      });

I am getting this error :

error is Looking up a deactivated widget's ancestor is unsafe. I/flutter ( 4699): At this point the state of the widget's element tree is no longer stable. I/flutter ( 4699): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor 

And I am unable to navigate to another screen but if I remove setState I am successfully navigating to another screen.

My code for login button click is as follows. isLoading starts with false and when its true, I show a circular progress indicator.

Future saveLogInData(BuildContext context) async {
    setState(() {
      isLoading = true;
    });
    final formState = _logInFormKey.currentState;
    if (formState.validate() ) {
      formState.save();
      try {
        Map<String, String> data = {
          "email": loginEmailController.text,
          "password": loginPasswordController.text,
        };
        print("my data is : $data");
        var response = await networkHandler.post("user/login", data);
        print("statuscode is ${response.statusCode}");
        if(response.statusCode == 200 || response.statusCode == 201){
          Map<String, dynamic> output = json.decode(response.body);
          print(output['token']);
          setState(() {
            validate = true;
            isLoading = false;
          });
          Navigator.push(
              context,
              MaterialPageRoute(
                  builder: (context) => Home(

                  )));

          
        }



        else{
          String output = json.decode(response.body);
          print("output is ${output}");
          setState(() {
            validate = false;
            isLoading = false;

          });
        }



        // user.sendEmailVerification();

      } catch (e) {
        print("error is $e}");
      } finally {

        isLoading = false;
      }
    } else {
      showDialog(
          context: context,
          builder: (BuildContext context) {
            return AlertDialog(
              title: Text("Error"),
              content: Text("Please check your email and password"),
              actions: <Widget>[
                FlatButton(
                  child: Text("Close"),
                  onPressed: () {
                    Navigator.of(context).pop();
                  },
                )
              ],
            );
          });
    }
  }
question from:https://stackoverflow.com/questions/65893344/flutter-error-is-looking-up-a-deactivated-widgets-ancestor-is-unsafe

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are setting the state after the widget is deactivated. Try adding this before setState to set it only if the widget is mounted:

if(mounted) setState(() => ...);

Alternatively, you can override the setState method to make all the setState calls safe:

@override
void setState(fn) {
    if(mounted) super.setState(fn);
}

You can also try pushing the route in the next frame if you want to change the state anyways:

WidgetsBinding.instance.addPostFrameCallback((_) {
    Navigator.of(context).push(...);
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...