Flutter:错误是查找已停用小部件的祖先是不安全的

Posted

技术标签:

【中文标题】Flutter:错误是查找已停用小部件的祖先是不安全的【英文标题】:Flutter : error is Looking up a deactivated widget's ancestor is unsafe 【发布时间】:2021-04-29 18:21:02 【问题描述】:

所以我尝试在我的颤振应用程序中使用 NodeJS 登录,并且我能够登录,但是当我在等待后端进程完成时尝试添加循环进度指示器时,当用户通过设置状态点击登录按钮时喜欢,

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

然后我登录成功后做,

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

我收到此错误:

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 

我无法导航到另一个屏幕,但如果我删除 setState,我将成功导航到另一个屏幕。

我的登录按钮点击代码如下。 isLoading 以 false 开头,当它为 true 时,我会显示一个圆形进度指示器。

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();
                  ,
                )
              ],
            );
          );
    
  

【问题讨论】:

【参考方案1】:

您正在设置小部件停用后的状态。尝试在 setState 之前添加它以仅在挂载小部件时设置它:

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

或者,您可以覆盖 setState 方法以使所有 setState 调用安全:

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


如果你想改变状态,你也可以尝试在下一帧推送路由:

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

【讨论】:

抱歉,没有一个方法奏效。我仍然收到Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method. 错误。如果我删除 setState 我导航很好。【参考方案2】:

我认为您应该删除 setState 并使用 ChangeNotifier。这将解决问题。

【讨论】:

以上是关于Flutter:错误是查找已停用小部件的祖先是不安全的的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:查找已停用小部件的祖先是不安全的

Flutter & Navigator & ImagePicker : 为啥我可以进入下一页?查找已停用小部件的祖先是不安全的

未处理的异常:查找已停用小部件的祖先是不安全的。如何解决这个问题?

提供者:查找已停用小部件的祖先是不安全的

使用提供程序和快餐栏查找已停用小部件的祖先是不安全的

尝试使用谷歌地图时查找已停用小部件的祖先是不安全的