
Navigator.of(context).push(); // 화면 전환
Fluttertoast.showToast(msg: "message"); // 토스트 메시지
Q. 위 두 함수는 UI와 관련이 있지만 왜
build과정의 영향을 받고 안 받고의 차이가 있을까?
MVVM패턴으로 앱을 구현해보는 중에 든 궁금증이다.
도대체 Buildcontext가 뭐길래 에러가 발생하는걸까?
이전 게시글에서 MVVM 패턴과 상태관리에 대해 다루면서 BuildContext 개념을 언급하였는데, 관련해서 추가 학습이 필요한 것 같으니 정리해보자.
BuildContext는 위젯 트리 내에서의 위치정보를 가지고 있으며, 위젯 트리 내 특정 부분을 탐색하거나 부모 위젯의 데이터를 가져오는 데 사용된다.
사용한 현재 context를 기준으로 위로 올라가면서 가장 가까운 위젯 또는 객체를 찾아 반환한다.
Provider.of<T>(context); // Provider
우리가 Provider에서 주입된 인스턴스를 사용하기 위해 작성했던 위 코드도, 해당 context기준 주입된 가장 가까운 T 타입의 객체를 찾기 위해서 사용되는 코드이다.
Navigator.of(context).push(); // Navigator
이어서 Buildcontext를 사용하여 할 수 있는 대표적인 작업이 바로 Navigator.of(context)를 사용하여 화면을 전환하는 것이다.
context를 기준으로 가장 가까은 Navigator를 찾고, Navigator에서 관리되는 Stack에 새로운 화면을 생성한다.
여기서 Navigator위젯은 최상위 MaterialApp이 생성될 때 기본적으로 1개가 같이 생성되며, 별도로 Stack 관리가 필요할 때 추가로 생성할 수 있다.
context가 새로 생성된 위젯의 위치 정보를 가지는 시점은 위젯의 build과정이 전부 진행되고 난 후이기 때문에 build이후 context를 사용해야 한다.
그렇기에 WidgetsBinding.instance.addPostFrameCallback과 같은 함수를 이용해서 프레임 렌더링이 끝나고 난 후 context를 사용하는 작업을 실행할 수 있도록 하는 것이다.
if (context.mounted) { // context 유효성 검사
...
}
같은 이유로, 비동기 함수는 메인 스레드가 아닌 event loop에서 동작하기 때문에, 비동기 함수 내에서 context를 사용할 때에는 위와 같이 mounted 프로퍼티를 사용하여 해당 context가 위젯 트리에 연결 되어있는지 검사 후 사용해야 한다.
Navigator.of(context).push(); // 화면 전환
Fluttertoast.showToast(msg: "message"); // 토스트 메시지
Q. 위 두 함수는 UI와 관련이 있지만 왜
build과정의 영향을 받고 안 받고의 차이가 있을까?
그러면 이제 내가 가지고 있었던 위 궁금증도 간단하게 해결이 된다.
A. 화면 전환 함수는
context를 사용하기 대문에 실행 시점이build과정의 영향을 받지만, 토스트 메시지를 띄우는 함수는context를 사용하지 않기 때문에build과정과는 무관하다.