코드 개선을 위해 Weak Warning을 정리하던 중, 이런 문장을 발견했다.
Don't use 'BuildContext's across async gaps.
위 문제에 해당하는 나의 코드는 아래와 같았다.
onPressed: () async {
∙∙∙
await onBackKey(); // onBackKey()는 내가 따로 만든 함수다.
Navigator.pop(context, true);
}
Flutter에서 BuildContext는 위젯 트리를 통해 현재 위젯의 위치를 식별하는 데 사용된다.
따라서 위젯 트리 내에서 현재 위치 및 상태를 나타내며, 위젯이 화면에 표시될 때 사용된다.
그런데, async가 포함된 함수 내에서 BuildContext를 사용하면
비동기 작업이 완료될 때까지 위젯 트리가 변경될 수 있으므로 BuildContext가 무효화될 수 있다.
그래서 Weak Warning으로 BuildContext를 사용하여 액세스하는 것은 위험하다고 표기하는 것 같다.
Flutter 3.7 이후로는 BuildContext에 mounted 라는 속성이 추가되었다.
mounted를 사용하면 코드를 아래와 같이 변환할 수 있다.
onPressed: () async {
∙∙∙
await onBackKey(); // onBackKey()는 내가 따로 만든 함수다.
if(context.mounted) Navigator.pop(context, true);
}
then을 사용하면 async, await 없이 코드를 아래와 같이 변환할 수 있다.
onPressed: () {
∙∙∙
onBackKey().then((_) { // onBackKey()는 내가 따로 만든 함수다.
Navigator.pop(context, true);
});
}
[참고자료]
Flutter 공식 유튜브 - mounted
블로그 - Flutter 3.7에서 context.mounted 사용하기
stack overflow - async 함수에서 BuildContext를 사용할 때 mounted 응용하기
await & async와 then의 차이점