일모도원(日暮途遠) 개발자

[Flutter오류수정] Don't use 'BuildContext's across async gaps. 본문

Flutter/오류수정

[Flutter오류수정] Don't use 'BuildContext's across async gaps.

달님개발자 2023. 8. 16. 10:15

async가 있는 함수내에서 "context"를 쓰면, 아래처럼 경고가 나온다.

Don't use 'BuildContext's across async gaps.

onTap: (value) async {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (_) {
        return EpubScreen.fromPath(filePath: file.path);
      },
    ),
  );

 

해결책은 아래처럼 "if (context.mount)" 구문으로 감싸면 된다.

onTap: (value) async {
  if (context.mounted) {
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) {
            return EpubScreen.fromPath(filePath: file.path);
          },
        ),
      );
    }

if (context.mounted)로 감싸면 해결은 되지만 이문구가 나오는 이유는 경고(警告)의 내용처럼  context가 비동기(非同期)함수 내에서 사용되기 때문이다. 

 

만약에 현 위젯내에서 Navigator.push로 다른 위젯으로 가는 코드가 여러개가 있을경우, 두개이상의 코드가 실행되면 문제가 발생될수 있을수 있다.

 

비동기 이기 때문에 A코드가 먼저 시작되었지만 Navigator.push가 실행되기 전에 많은 작업을 하고 있는 동안, B코드가 실행되어 Navigator.push를 통하여 다른 위젯으로 가버리면, 현재 위젯의 context는 사라진다.

 

이때 A코드가 Navigator.push를 실행시킬려고 하면 context가 없기 때문에 문제가 된다.(B코드에서 이미 다른 위젯으로 가버렸기 때문)

 

이를 방지하기 위해서 Navigator.push를 실행하기 전에 context가 제대로 mount되어 있는지 확인하면 저 경고가 없어진다. (테스트 해보니 context != null로 는 저 경고가 없어지지 않는다. mount여부를 확인해야 하는거 같다.)

 

  /// 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 unmounted, a given [BuildContext] will never become mounted again.
  ///
  /// {@macro flutter.widgets.BuildContext.asynchronous_gap}
  bool get mounted;

 

저건 일일히 if문으로 감싸지 않아도 자체적으로 context가 mount되어 있지 않으면 push가 되지 않게 처리해줬으면 한다.