본문 바로가기
Flutter

error Looking up a deactivated widget's ancestor is unsafe [Flutter]

by 난타코다옹 2023. 11. 1.

목차

    아래 오류는 플러터(Flutter)를 처음 접하는 개발자부터 중급 이상의 개발자까지 두루 접하게 되는 문제인 것 같아요!

    저도 개발하면서 몇 번이나 만났는지 몰라요ㅎㅎ

    다시 보니 새롭죠? 😆

    Error 내용

    Looking up a deactivated widget's ancestor is unsafe.

    이 오류는 주로 다이얼로그(Dialog)나 모달(Modal) 창을 사용할 때 발생하는 문제인데요, 특히 텍스트 필드를 클릭할 때 발생하는 경우가 많아요.

    에러 발생 코드

    show(BuildContext context){
    
        var dialog = Dialog(
          child: Container(
            margin: EdgeInsets.all(8.0),
            child: Form(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  TextFormField(
                    decoration: InputDecoration(
                        labelText: "Insira o número de telefone",
                        border: OutlineInputBorder(
                            borderRadius: BorderRadius.all(Radius.circular(2.0)))),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      FlatButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text("Cancelar")),
                      FlatButton(
                          onPressed: () {
                            Navigator.of(context).pop();
                          },
                          child: Text("Aceitar"))
                    ],
                  )
                ],
              ),
            ),
          ),
        );
    
        showDialog(context: context,builder: (context){
          return dialog;
        });
      }

    위의 코드는 잘 작동하지 않아요. 왜 그럴까요? 😅

    해당 코드를 작동할 때 나오는 로그에요ㅎㅎ 같이 살펴볼까요?

    로그

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

    위의 로그를 자세히 읽어보면 몇 가지 해결 방법을 추천해 주고 있네요~~ 😇

    우선, 이 에러가 발생한 원인부터 살펴봐요.

    원인

    이 오류는 다이얼로그(Dialog)나 모달(Modal) 창을 사용할 때 발생하는 문제인데요, 다이얼로그나 모달 창이 닫힌 후에도 해당 위젯이 여전히 활성화된 상태로 남아있어서 발생하는 문제예요. 이런 상황에서 위젯의 상위 위젯을 찾으려고 하면 위험하다는 경고가 나타나는 거죠.

    그럼 어떻게 해결해야 할까요?

    몇 가지 해결책을 알려드릴게요 😎

    해결책

    1. Dialog 대신 AlertDialog를 사용해보세요.
      showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text("Insira o número de telefone"), content: TextFormField( decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(2.0)), ), ), ), actions: <Widget>[ FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: Text("Cancelar"), ), FlatButton( onPressed: () { Navigator.of(context).pop(); }, child: Text("Aceitar"), ), ], ); }, );
    2. 다이얼로그를 사용할 때 Navigator.of(context).pop()을 호출하기 전에 FocusScope를 사용하여 포커스를 해제해보세요.

    결론

    이 문제는 다이얼로그(Dialog)나 모달(Modal) 창을 사용할 때 발생하는 문제로, 다이얼로그가 닫힌 후에도 해당 위젯이 여전히 활성화된 상태로 남아있어서 발생하는 문제예요. 이를 해결하기 위해서는 AlertDialog를 사용하거나 FocusScope를 사용하여 포커스를 해제해야 해요.

    앞으로.. 예방법!

    이와 같은 오류를 예방하려면 다이얼로그(Dialog)나 모달(Modal) 창을 사용할 때 주의해야 해요. 다이얼로그나 모달 창이 닫힌 후에는 해당 위젯이 활성화되지 않도록 해야 해요. 이를 위해 AlertDialog를 사용하거나 FocusScope를 사용하여 포커스를 해제할 수 있어요.