[Flutter] mounted에 대한 이해

Chance·2025년 6월 18일

✅ 요약

mounted는 해당 State 객체가 아직 화면에 존재하는지 여부를 확인하는 Boolean 값입니다.

🧠 왜 필요한가?

비동기 작업 중 위젯이 dispose될 수 있기 때문


void initState() {
  super.initState();
  fetchData(); // 비동기 호출
}

Future<void> fetchData() async {
  final result = await SomeApi.call();

  setState(() {  // ⚠️ 이때 이 State는 이미 dispose됐을 수도 있음
    data = result;
  });
}

👉 이 경우, 비동기 작업 도중 사용자가 페이지를 나가버리면 State는 dispose 되지만, fetchData()는 계속 실행되고 있음.

setState()는 dispose된 상태에서 호출되면 예외 발생:

Unhandled Exception: setState() called after dispose()

해당 에러 발생조건 예시

final data = await API();

// ⚠️ 이때 이 State는 이미 dispose됐을 수도 있음
setState(() {
	temp = data;
})

절차

  1. API실행중에 사용자가 화면을 벗어남(뒤로가기, 강제종료 등등)
  2. API는 계속 실행 중
  3. dispose실행으로 화면의 위젯트리 제거
  4. API실행이 완료되어 setState실행
  5. rebuild될 위젯이 없기 때문에 에러 발생


비동기 뿐만 아니라 Context접근 또한 마찬가지

✅ 이유 요약

Flutter에서는 BuildContext도 위젯 트리에 붙어 있는 동안만 유효하기 때문입니다.
→ 해당 위젯이 dispose()되면 context도 함께 무효화됩니다.

🔥 예외가 발생하는 대표적 상황

예: 비동기 작업 후 context로 Navigator 호출

Future<void> asyncLogin() async {
  final result = await loginApi();

  // ⚠️ 페이지가 dispose된 상태일 수 있음
  Navigator.pushNamed(context, '/home');  // ❌ 예외 발생 가능
}

만약 사용자가 API 요청 중 뒤로 가기를 눌러버리면, 해당 StatefulWidget은 dispose()되고 context는 무효가 됨

그런데 Navigator.push는 죽은 context를 쓰게 되므로 예외 발생

0개의 댓글