Flutter의 Navigator 2.0과 go_router 비교 및 사용법
Flutter에서 라우팅은 애플리케이션의 여러 화면 간을 이동하고, 사용자의 입력에 따라 경로를 변경하는 데 중요한 역할을 합니다. Flutter는 기본적으로 Navigator를 통해 라우팅을 제공합니다. 특히 Navigator 2.0은 복잡한 라우팅 요구사항을 충족하기 위해 개선되었으며, go_router는 이러한 복잡성을 단순화한 강력한 패키지로 많은 개발자들이 사용하고 있습니다.
이 글에서는 Navigator 2.0과 go_router의 차이점을 비교하고, 각 방법의 구현 방법과 장단점을 예제와 함께 소개합니다.
📌 1. Navigator 2.0이란?
Flutter 1.22 버전에서 도입된 Navigator 2.0은 기존의 Navigator 1.0보다 더 유연하고 복잡한 라우팅 요구 사항을 해결할 수 있도록 개선된 라우팅 시스템입니다. 특히 웹 브라우저의 URL을 반영하거나 딥 링크와 같은 기능을 쉽게 구현할 수 있도록 설계되었습니다.
✅ 주요 특징
- 상태 기반 라우팅: URL과 애플리케이션 상태 동기화
- 딥 링크 지원: 외부에서 앱의 특정 화면으로 바로 진입
- 복잡한 내비게이션 흐름 처리: 다중 경로, 동적 라우팅 구현 가능
📦 설치
Flutter 자체 기능으로 제공되므로 별도의 설치는 필요 없습니다.
📊 기본 사용 예제
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerDelegate: MyRouterDelegate(),
routeInformationParser: MyRouteInformationParser(),
);
}
}
class MyRouterDelegate extends RouterDelegate<String>
with ChangeNotifier, PopNavigatorRouterDelegateMixin {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
String? _path;
@override
Widget build(BuildContext context) {
return Navigator(
key: navigatorKey,
pages: [
const MaterialPage(child: HomePage()),
if (_path == '/details') const MaterialPage(child: DetailsPage()),
],
onPopPage: (route, result) {
if (!route.didPop(result)) return false;
_path = null;
notifyListeners();
return true;
},
);
}
@override
Future<void> setNewRoutePath(String path) async {
_path = path;
notifyListeners();
}
}
class MyRouteInformationParser extends RouteInformationParser<String> {
@override
Future<String> parseRouteInformation(RouteInformation routeInformation) async {
return routeInformation.location ?? '/';
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('홈')),
body: Center(
child: ElevatedButton(
onPressed: () {
(Router.of(context).routerDelegate as MyRouterDelegate)
.setNewRoutePath('/details');
},
child: const Text('상세 페이지로 이동'),
),
),
);
}
}
class DetailsPage extends StatelessWidget {
const DetailsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('상세 페이지')),
body: const Center(child: Text('상세 페이지입니다.')),
);
}
}
📌 2. go_router란?
go_router는 Flutter 공식 패키지로, Navigator 2.0의 복잡함을 줄이고 간편하게 라우팅을 구현하도록 돕습니다. URL 기반의 라우팅과 딥 링크를 손쉽게 지원하며, 구성 방식이 직관적이라 사용하기 쉽습니다.
✅ 주요 특징
- 간편한 라우팅 설정: 복잡한 라우팅 로직을 간단하게 구현
- 딥 링크 지원: 외부 URL로 앱 내 특정 화면 이동
- 상태 관리와 통합: Riverpod, Provider와 쉽게 연동
📦 설치
flutter pub add go_router
📊 기본 사용 예제
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: _router,
);
}
}
final GoRouter _router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => const HomePage()),
GoRoute(path: '/details', builder: (context, state) => const DetailsPage()),
],
);
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('홈')),
body: Center(
child: ElevatedButton(
onPressed: () => context.go('/details'),
child: const Text('상세 페이지로 이동'),
),
),
);
}
}
class DetailsPage extends StatelessWidget {
const DetailsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('상세 페이지')),
body: const Center(child: Text('상세 페이지입니다.')),
);
}
}
📌 3. Navigator 2.0 vs go_router 비교
항목 | Navigator 2.0 | go_router |
설정 난이도 | 복잡함 (RouterDelegate, Parser) | 간단함 (GoRoute 기반 설정) |
딥 링크 | 직접 구현 필요 | 기본 지원 |
상태 기반 라우팅 | 가능 | 가능 |
네비게이션 | 수동으로 상태 관리 | context.go()로 간편하게 관리 |
권장 사용처 | 복잡한 사용자 정의 라우팅 필요 시 | 대부분의 일반 라우팅에 적합 |
📌 4. 결론
- Navigator 2.0: 복잡한 라우팅, 사용자 정의가 필요한 경우 적합
- go_router: 간편한 설정과 딥 링크 지원이 필요한 경우 추천
프로젝트의 요구사항에 맞춰 적절한 라우팅 방식을 선택하세요!
'Flutter' 카테고리의 다른 글
Flutter CustomPainter를 사용한 커스텀 드로잉 (0) | 2025.01.18 |
---|---|
Flutter 애니메이션: AnimationController vs TweenAnimationBuilder (0) | 2025.01.18 |
Flutter Hooks와 hooks_riverpod의 활용법 (0) | 2025.01.18 |
AutoDispose와 keepAlive의 차이점 완벽 정리 (0) | 2025.01.17 |
ProviderScope와 overrideWithProvider의 활용법 (0) | 2025.01.17 |