Flutter Mounted에 관하여

2025. 8. 9. 20:40

인턴 활동을 하면서 처음 봤던 것 중에 mounted 확인이 있었다. mount는 이전에 앱을 만들때 사용해본 적이 없어서 무슨 기능인지 이번 기회에 알아보려고 한다.

우선 mounted라는 말은 무엇일까? ed가 붙으면 수동형이 되는데 mount는 여러가지의 의미가 있지만 명사형의 의미중에

장치
어떤 것을 지지하거나 고정하는 데 사용되는 장치를 의미합니다. 예시: "a camera mount" (카메라 거치대)

라는 의미가 있습니다.  그러면 flutter Mounted의 의미로 해석을 해보자면 "연결이 되었다" 정도로 해석을 해보고 넘어가 보겠습니다.

 

간단하게 알아보기

그 다음으로 공식 사이트를 찾아보겠습니다. 검색을 해보면 공식 사이트에선 state와 element에 대해서 두가지의 mounted 설명이 나옵니다.

https://api.flutter.dev/flutter/widgets/State/mounted.html

 

mounted property - State class - widgets library - Dart API

 

api.flutter.dev

https://api.flutter.dev/flutter/widgets/Element/mounted.html

 

mounted property - Element class - widgets library - Dart API

Whether the Widget this context is associated with is currently mounted in the widget tree. Accessing the properties of the BuildContext or calling any methods on it is only valid while mounted is true. If mounted is false, assertions will trigger. Once un

api.flutter.dev

State와 Element에 대한 내용이 있는 것을 확인할 수 있습니다. 

State class에서 mounetd는 "Whether this State object is currently in a tree." : " 이 State 객체가 현재 트리에 있는지 여부"

Element class에서 mounted는 "Whether the Widget this context is associated with is currently mounted in the widget tree." : " 이 컨텍스트가 연관된 위젯이 현재 위젯 트리에 마운트되어 있는지 여부"

두가지를 설명을 간단하게 보자면 현재 위젯트리에 마운트가 되어있는지의 여부를 확인하기 위해서 쓴다는 것을 알 수 있습니다.

 

좀더 알아보기

좀더 자세하게 알아보겠습니다. 결국 flutter에서 mounted로 확인하는것은 현재의 하려는 작업을 위해서 위젯트리에 마운트가 되어있다 연결이 되어있다는 것을 확인하는 작업이라는 것은 알았습니다..

그런데 왜 두가지로 구분을 해서 설명을 하고 있는지에 대해서는 의문이 생깁니다. 결국 monted로 오류를 줄이기 위해서 사용합니다만 약간의 차이가 있습니다.

먼저 state는 Stateful wigdet에서 비동기로 state를 불어올때 그 사이에 사용자가 화면을 이동할 상황이 있을 경우 state가 맞는 화면에서 불러와지는 것인지를 확인하는 작업입니다. 코드를 예시로 보겠습니다.

  Future<void> _loadData() async {
    await Future.delayed(const Duration(seconds: 2));

    if (mounted) {
      setState(() {
        _message = '데이터 로딩 완료!';
      });
      print('데이터 로딩 완료 후 setState 호출됨!');
    } else {
      print('앗! 위젯이 이미 사라져서 setState를 호출할 수 없어요!');
    }
  }

위 함수가 있습니다. 이 함수가 작동될때는 delayed로 2초라는 gap 이후에 state를 불러오고있습니다. 2초라는 gap동안 사용자가 화면을 이동했을때는 setstate가 이동된 화면에서 불필요한 상태가 전달되서 오류가 발생할 가능성이 발생되니다. 이때 mounted로 위젯 트리를 확인해서 오류의 가능성을 제거하는 것입니다.

다음으로 Element도 비슷합니다. state를 사용하지 않고 buildcontext 안에서 비동기적인 상황이 발생할때 builidcontext의 변화가 발생해서 맞는 buildcontext가 위젯트리에 mounted되어있는지를 확인하는 것입니다.

ElevatedButton(
  onPressed: () async {
    print('버튼 눌림! 2초 기다립니다...');
    await Future.delayed(const Duration(seconds: 2));
    if (context.mounted) {
      print('context가 아직 마운트되어 있어서 Navigator.pop() 호출!');
      Navigator.of(context).pop(); // 이전 화면으로 돌아가기
    } else {
      print('앗! context가 이미 사라져서 Navigator.pop()을 호출할 수 없어요!');
    }
  },
  child: const Text('돌아가기'),
),

코드를 보시면 elevatedbutton이 있는데 버튼을 누르면 2초의 gap이 생기게 됩니다. 그리고 그 사이에 역시 유저가 화면을 이동할 가능성이 생기게 됩니다. 그러면 buildcontext가 변할 수가 있는데 이때 mounted를 이용해서 올바른 buildcontext임을 확인하고 이후의 작업을 실행할지를 정하게 되는 방식입니다.

코딩을 하다가 문제가 발생하는 부분에서 mounted를 확인하면 쉽게 해결할 수 있는 방식입니다. 그런데 더 좋은 방식이 존재합니다. state에서의 mounted는 setstate를 이용해서 상태를 관리할때 문제가 될 수 있는 것입니다. 그런데 setState가 아닌 상태 관리 라이브러리를 사용하면 문제가 자동으로 해결되게 됩니다. ui가 dispose되면 자동으로 상태와 ui의 구독이 끊어지기 때문입니다. 그렇지만 buildContext와 관련해서는 여전히 문제가 발생할 가능성이있습니다. 그래서 상태관리 라이브러리를 사용하더라도 문제가 발생하는 부분에서는 buildcontext이 mounted를 확인해야합니다.

 

결론

state는 상태관리 라이브러리를 사용하면 자동으로 문제가 해결된다. 그렇지만 buildcontext에서의 mounted 문제는 직접 확인을 해야한다.

반응형

'Flutter > 한달 인턴' 카테고리의 다른 글

Future to Stream  (1) 2025.06.30
Navigate with named routes  (1) 2025.06.24

BELATED ARTICLES

more