gorouter 기본사용법

topics 500-모바일개발 501 Flutter
types 실습 레퍼런스
tags
references pitching-gap.tistory.com/entry/Flutte... medium.com/@madhanrkv10/authenticatio... github.com/lucavenir/go_router_riverpod

GoRouter 기본 사용법

Flutter에서 페이지 라우팅을 관리하는 GoRouter 패키지의 사용법이다.

Why GoRouter

왜 GoRouter를 쓸까: Navigator 2.0은 너무 복잡하다. GoRouter는 선언적 라우팅을 간단하게 사용할 수 있게 해준다. 딥링크, 웹 URL 지원도 기본 제공된다.

설치

dependencies:
  go_router: ^latest_version

기본 설정

라우터 정의

final goRouter = GoRouter(
  initialLocation: '/',
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomeScreen(),
    ),
    GoRoute(
      path: '/details/:id',
      builder: (context, state) {
        final id = state.pathParameters['id']!;
        return DetailsScreen(id: id);
      },
    ),
    GoRoute(
      path: '/settings',
      builder: (context, state) => const SettingsScreen(),
    ),
  ],
);

MaterialApp에 연결

MaterialApp.router(
  routerConfig: goRouter,
)

페이지 이동

기본 이동

// path로 이동
context.go('/details/123');

// push (뒤로가기 가능)
context.push('/settings');

// pop (뒤로가기)
context.pop();

go vs push

메소드 동작 사용 시점
go() 스택 교체 탭 전환, 로그아웃 후 이동
push() 스택에 추가 상세 페이지, 뒤로가기 필요할 때

주의: go()는 현재 스택을 완전히 교체한다. 뒤로가기가 필요하면 push()를 써야 한다.

중첩 라우트

GoRoute(
  path: '/family/:fid',
  builder: (context, state) => FamilyScreen(
    fid: state.pathParameters['fid']!,
  ),
  routes: [
    GoRoute(
      path: 'person/:pid',
      builder: (context, state) => PersonScreen(
        fid: state.pathParameters['fid']!,
        pid: state.pathParameters['pid']!,
      ),
    ),
  ],
),

/family/123/person/456 이런 식으로 접근 가능하다.

리다이렉트

final goRouter = GoRouter(
  redirect: (context, state) {
    final isLoggedIn = authState.isLoggedIn;
    final isLoginRoute = state.matchedLocation == '/login';

    if (!isLoggedIn && !isLoginRoute) {
      return '/login';
    }
    if (isLoggedIn && isLoginRoute) {
      return '/';
    }
    return null;  // 리다이렉트 없음
  },
  routes: [...],
);

Riverpod와 함께 사용하기

Provider로 GoRouter 관리

final goRouterProvider = Provider<GoRouter>((ref) {
  final authState = ref.watch(authProvider);

  return GoRouter(
    refreshListenable: authState,
    redirect: (context, state) {
      final isLoggedIn = authState.isLoggedIn;
      final isLoginRoute = state.matchedLocation == '/login';

      if (!isLoggedIn && !isLoginRoute) return '/login';
      if (isLoggedIn && isLoginRoute) return '/';
      return null;
    },
    routes: [...],
  );
});

왜 이렇게 하냐면: 인증 상태가 바뀔 때마다 자동으로 리다이렉트된다. 로그인/로그아웃 시 수동으로 페이지 이동 안 해도 된다.

MaterialApp에 연결

class App extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final router = ref.watch(goRouterProvider);
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

ShellRoute - 공통 레이아웃

여러 페이지에서 같은 레이아웃(예: 하단 네비게이션)을 공유할 때 사용한다.

ShellRoute(
  builder: (context, state, child) {
    return ScaffoldWithNavBar(child: child);
  },
  routes: [
    GoRoute(path: '/home', builder: ...),
    GoRoute(path: '/search', builder: ...),
    GoRoute(path: '/profile', builder: ...),
  ],
),

관련 문서