2025. 4. 23. 17:26ㆍProgramming/Flutter
Flutter의 GoRouter를 사용해서 라우트를 구현하던 중, 전체 페이지에 공용으로 출력해야하는 UI를 라우터에 따라 변경해야하는 일이 있었습니다. RouterDelegate.addListener()를 호출해서 이벤트 핸들러를 등록해서, 라우트가 변경될 때마다 ValueNotifier의 값을 변경하는 방식으로 UI를 업데이트하여 간단하게 해결... 된다고 생각했지만, RouterDelegate.currentConfiguration.uri를 참조해서 업데이트하도록 작성했더니, push()를 사용해서 페이지를 이동했을 때는 ValueNotifier가 정상적으로 업데이트되지 않았습니다.
한참을 고민하던 중 RouterDelegate.currentConfiguration.uri를 참조하는 대신, RouteInformationProvider.value.uri를 참조하도록 변경했더니 push()/pop()을 할 때도 정상적으로 동작하는 걸 확인할 수 있었죠. 그런고로 이번에는 RouterDelegate와 RouteInformationProvider가 어떤 역할을 하는지 정리해보려고 합니다.
GoRouter의 핵심 컴포넌트
RouterDelegate
RouterDelegate는 Flutter의 Navigator 2.0에서 도입된 핵심 컴포넌트로 구현 목적은 다음과 같습니다.
상태 관리
- 전체 네비게이션 스택의 상태를 관리
- 라우팅 상태를 앱의 상태로 취급
선언적 API 제공
- 명령형 네비게이션(push, pop)을 선언적 방식으로 변환
- 라우트 구성을 객체로 표현
딥링크 처리
- 외부 URL을 앱 내부 상태로 변환
- 앱의 상태를 URL로 변환
RouteInformationProvider
RouteInformationProvider는 현재 라우트 정보를 제공하는 컴포넌트로 구현 목적은 다음과 같습니다.
플랫폼 통합
- 브라우저 URL 변경 감지
- 시스템 백 버튼 처리
- 딥링크 처리를 위한 플랫폼 수준의 통합
라우트 정보 추상화
- 플랫폼 독립적인 라우트 정보 제공
- URL 기반 라우팅을 위한 표준화된 인터페이스 제공
RouterDelegate vs RouteInformationProvider
RouterDelegate
final currentPath = router.routerDelegate.currentConfiguration.uri.toString();
특징:
- 네비게이션 스택의 전체 상태를 관리
- 라우팅 로직을 처리하는 핵심 컴포넌트
- 이전 라우트 정보를 참조할 수 있음
- 상태 변경이 실제 네비게이션 완료 전에 발생할 수 있음
단점:
currentConfiguration
이 항상 최신 상태를 반영하지 않을 수 있음- push 작업 시 이전 경로를 참조하는 경우가 발생
RouteInformationProvider
final currentPath = router.routeInformationProvider.value.uri.toString();
특징:
- 현재 라우트의 정보만을 제공
- 항상 스택의 최상단에 있는 페이지의 URI를 정확하게 반영
- 실제 네비게이션이 완료된 후의 상태를 제공
- URL 기반 라우팅에 더 적합
장점:
- 더 정확한 현재 경로 정보를 제공
- 네비게이션 완료 후의 실제 상태를 반영
실제 사용 예시
// 권장되는 방식
router.routerDelegate.addListener(() {
final currentPath = router.routeInformationProvider.value.uri.toString();
if (notifier.value != currentPath) {
notifier.value = currentPath;
}
});
이 방식에서는:
routerDelegate
의 리스너를 통해 모든 네비게이션 이벤트(push, pop, replace)를 감지routeInformationProvider
를 통해 정확한 현재 경로 정보를 획득
동작 방식
네비게이션 이벤트 발생 시:
사용자 액션(push/pop/replace) → RouterDelegate 상태 변경 → 네비게이션 수행 → RouteInformationProvider 업데이트
딥링크나 URL 변경 시:
외부 URL/딥링크 → RouteInformationProvider 업데이트 → RouterDelegate가 해당 정보를 기반으로 네비게이션 수행
결론
라우트 변경을 감지할 때는 RouterDelegate
의 리스너를 사용하고, 현재 경로 정보를 얻을 때는 RouteInformationProvider
를 사용하는 것이 가장 안정적인 방법입니다. 이는 모든 네비게이션 이벤트를 놓치지 않으면서도 정확한 현재 경로 정보를 얻을 수 있게 해줍니다.
참조자료
'Programming > Flutter' 카테고리의 다른 글
[Flutter/iOS] 자체서명 인증서(Self-signed certificate)를 우회한 HLS 스트리밍 구현 / GCDWebServer를 사용한 로컬 프록시 서버 구현 (1) | 2025.04.21 |
---|---|
[Flutter] Isolate를 활용한 HTTP 클라이언트 리팩토링과 iOS에서 Isolate 초기화 문제 (0) | 2025.04.11 |
Sign in with Apple: iOS에서는 실패하는데 Android/Web에서는 성공하는 경우? (0) | 2025.04.09 |
[Flutter] 때때로 생성자에서 비동기 요청을 하게되면, 비동기 요청이 실행되기 전에 dispose()가 호출될 수도 있다. (0) | 2025.03.18 |
[Dart] Completer를 사용한 비동기 제어 (0) | 2025.01.15 |