본문 바로가기
Flutter

Flutter의 Navigator 2.0과 go_router 비교 및 사용법

by 안될개발 2025. 1. 18.

Flutter에서 Navigator 2.0과 go_router 비교 및 사용법

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: 간편한 설정과 딥 링크 지원이 필요한 경우 추천

프로젝트의 요구사항에 맞춰 적절한 라우팅 방식을 선택하세요!