본문 바로가기
Flutter

No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of() [flutter] error

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

목차

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

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

    다시 보니 새롭죠? 😆

    Error

    No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().

    이 오류는 MediaQuery를 사용할 때 발생하는 문제인데요, 해당 오류가 발생한 이유와 해결 방법에 대해 알아보도록 할게요!

    우선, 해당 오류가 발생하는 코드부터 살펴봐요 😄

    에러 발생 코드

    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('NoteIndex'),
            centerTitle: true,
          ),
          body: ListView.builder(
              itemCount: 10,
              itemBuilder: (context, index) {
                return Card(
                  child: ListTile(
                    onTap: () {},
                    title: (Text(locs[index].note)),
                  ),
                );
              }),
        );
      }
    }
    
    class Sala {
      String note;
      String noteDes;
      Sala({this.note, this.noteDes});
    }

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

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

    로그

    I/flutter (21388): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
    I/flutter (21388): The following assertion was thrown building MyApp:
    I/flutter (21388): MediaQuery.of() called with a context that does not contain a MediaQuery.
    I/flutter (21388): No MediaQuery ancestor could be found starting from the context that was passed to MediaQuery.of().
    I/flutter (21388): This can happen because you do not have a WidgetsApp or MaterialApp widget (those widgets introduce
    I/flutter (21388): a MediaQuery), or it can happen if the context you use comes from a widget above those widgets.
    I/flutter (21388): The context used was:
    I/flutter (21388):   Scaffold
    I/flutter (21388): 
    I/flutter (21388): The relevant error-causing widget was:
    I/flutter (21388):   MyApp file:///F:/FlutterProjects/notesgenerator/lib/main.dart:6:23
    I/flutter (21388): 
    I/flutter (21388): When the exception was thrown, this was the stack:
    I/flutter (21388): #0      MediaQuery.of (package:flutter/src/widgets/media_query.dart:798:5)
    I/flutter (21388): #1      ScaffoldState.didChangeDependencies (package:flutter/src/material/scaffold.dart:1993:50)
    I/flutter (21388): #2      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4376:12)
    I/flutter (21388): #3      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4201:5)
    I/flutter (21388): #4      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3194:14)
    I/flutter (21388): #5      Element.updateChild (package:flutter/src/widgets/framework.dart:2988:12)
    I/flutter (21388): #6      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4243:16)
    I/flutter (21388): #7      Element.rebuild (package:flutter/src/widgets/framework.dart:3947:5)
    I/flutter (21388): #8      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4206:5)
    I/flutter (21388): #9      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4201:5)
    I/flutter (21388): #10     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3194:14)
    I/flutter (21388): #11     Element.updateChild (package:flutter/src/widgets/framework.dart:2988:12)
    I/flutter (21388): #12     RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1028:16)
    I/flutter (21388): #13     RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:999:5)
    I/flutter (21388): #14     RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:942:17)
    I/flutter (21388): #15     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2412:19)
    I/flutter (21388): #16     RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:941:13)
    I/flutter (21388): #17     WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:819:7)
    I/flutter (21388): #18     WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:804:7)
    I/flutter (21388): #27     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:384:19)
    I/flutter (21388): #28     _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:418:5)
    I/flutter (21388): #29     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:174:12)
    I/flutter (21388): (elided 8 frames from package dart:async and package dart:async-patch)
    I/flutter (21388): 
    I/flutter (21388): ════════════════════════════════════════════════════════════════════════════════════════════════════

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

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

    원인

    해당 오류는 MediaQuery를 사용할 때 MediaQuery의 조상 위젯이 없는 경우 발생해요. 이런 경우 WidgetsApp 또는 MaterialApp 위젯을 사용하지 않았거나, 사용한 컨텍스트가 해당 위젯들의 상위 위젯에서 가져온 것이 아닐 수 있어요.

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

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

    해결책

    1. MaterialApp 위젯으로 앱을 감싸기
      void main() => runApp(MaterialApp( home: MyApp(), ));
    2. WidgetsApp 위젯으로 앱을 감싸기
      void main() => runApp(WidgetsApp( home: MyApp(), ));
    3. MediaQuery를 사용하기 위해 Builder 위젯 사용하기

    결론
    이 문제는 MediaQuery를 사용할 때 MediaQuery의 조상 위젯이 없는 경우 발생하는 문제에요. 이를 해결하기 위해서는 MaterialApp 또는 WidgetsApp 위젯으로 앱을 감싸거나, Builder 위젯을 사용하여 MediaQuery를 사용해야 해요!

    앞으로.. 예방법!
    이와 같은 오류를 예방하려면 MediaQuery를 사용할 때 MediaQuery의 조상 위젯이 존재하는지 확인해야 해요. 만약 조상 위젯이 없다면 MaterialApp 또는 WidgetsApp 위젯으로 앱을 감싸거나, Builder 위젯을 사용하여 MediaQuery를 사용해야 해요ㅎㅎㅎㅎㅎㅎ