[Flutter] A GlobalKey was used multiple times inside one widget's child list
2023. 3. 6. 22:45ㆍDevelopers 공간 [Shorts]/Frontend
728x90
반응형
<분류>
A. 수단
- OS/Platform/Tool : Linux, Kubernetes(k8s), Docker, AWS
- Package Manager : node.js, yarn, brew,
- Compiler/Transpillar : React, Nvcc, gcc/g++, Babel, Flutter
- Module Bundler : React, Webpack, Parcel
B. 언어
- C/C++, python, Javacsript, Typescript, Go-Lang, CUDA, Dart, HTML/CSS
C. 라이브러리 및 프레임워크 및 SDK
- OpenCV, OpenCL, FastAPI, PyTorch, Tensorflow, Nsight
1. What? (현상)
The following assertion was thrown building _FocusMarker:
Expected [ShellViewArguments], found [null]
The relevant error-causing widget was: MaterialApp
The following assertion was thrown building _FocusMarker:
A GlobalKey was used multiple times inside one widget's child list.
The offending GlobalKey was: [LabeledGlobalKey<NavigatorState>#1c06b Key Created by default]
The parent of the widgets with that key was: _FocusMarker
The first child to get instantiated with that key became:
Navigator-[LabeledGlobalKey<NavigatorState>#1c06b Key Created by default]
Widget이 정상적으로 뜨고 나서, 새로고침을 하니 반복적으로 위와 같은 에러가납니다.
2. Why? (원인)
- Global Key란?
- 위젯을 위한 Widget Tree와 같이 Element Tree가 있습니다. Widget은 렌더링하는데 필요한 정보를 모두 가지고 있는반면, Element Tree는 해당 위젯들에 대한 포인터 같은 것이라고 생각하면 좋습니다.
(예를 들어, 위젯의 순서가 바뀌면, Element Tree도 바뀌어야합니다.) - 위젯이 바뀌었다면, 위젯들과 Element가 매칭되는 것을 이 Global Key가 돕는 것이며, 상위 위젯에 적용하면 하위 위젯에까지 적용됩니다.
- Stateless 위젯 : State 변경이 불가능한 위젯으로 화면 렌더링 이후 데이터의 변경이 없습니다. 따라서 key가 필요없습니다.
- Stateful 위젯 : State 변경이 가능한 위젯으로 데이터 변경마다 다시 렌더링 합니다. 따라서 key가 필요합니다.
- 종류 : ValueKey, ObjectKey, UniqueKey, PageStorageKey, GlobalKey 등이 있지만, Global key는 전역 변수와 비슷한 개념의 key이며, Redux와 Bloc같이 상태 공유를위한 패턴입니다.
- 구현 방법 :
- 글로벌 키 선언 :
final 키이름 = GlobalKey<타입>(); - stateful 위젯의 경우 key를 상속받을 수 있도록 생성자를 아래와 같이 구성
class 위젯 extends StatefulWidget {
위젯({Key key}) : super(key: key); // Key를 받는 생성자 구성
.... - 키의 타입이 정해져있으므로 메서드를 활용할 수도 있습니다.
키이름.currentState!.메서드();
- 글로벌 키 선언 :
- 위젯을 위한 Widget Tree와 같이 Element Tree가 있습니다. Widget은 렌더링하는데 필요한 정보를 모두 가지고 있는반면, Element Tree는 해당 위젯들에 대한 포인터 같은 것이라고 생각하면 좋습니다.
- 저의 경우엔 Stacked 패키지를 활용했는데 Stacked 패키지의 Navigator는 페이지간 이동을 도와주며 이때 Global Key를 활용하는 것 같습니다.
- 새로고침을 하면 Navigator를 활용한 페이지 로딩을 시도하는데, 페이지 로딩에 문제가 있어 Navigation이 불가해지면서 Global key와 관련한 문제처럼 에러가 뜬 것이었습니다.
- 페이지의 문제 : 페이지의 Arguments가 있었는데, 기존에는 Landing Page를 통해 전달하던 것이 새로고침을 하니 Arguments를 넘겨줄 방법이 없어서 null 값으로 argument가 들어가고 있었습니다.
3. How? (해결책)
- 새로고침이 가능한 페이지의 생성자에는 Argument를 없애니 에러가 사라졌습니다.
728x90
반응형
'Developers 공간 [Shorts] > Frontend' 카테고리의 다른 글
[Flutter] 카카오 API 활용하기 위한 셋팅 (0) | 2023.03.12 |
---|---|
[Flutter] List, ListView, ListView.Builder 차이 (0) | 2023.03.11 |
[Flutter] Conditonal 하게 Rendering하는 방법 (0) | 2023.03.05 |
[Flutter] Stacked 패키지에서 initState가 동작을 안한다? (State에 대해서....) (0) | 2023.03.05 |
[Flutter] 내부 widget이 부여받은 사이즈로 구성하는 방법 (0) | 2023.03.05 |