[Flutter]go_router로 라우팅 관리

한상욱·2024년 8월 19일
0

Flutter

목록 보기
15/26
post-thumbnail

들어가며

Flutter에서는 UI 화면간 라우팅 및 딥링크 처리를 위하여 Navigator를 이용합니다. Navigator를 이용해도 훌륭한 라우팅을 구축할 수 있는데요. 더욱 간편하게 라우팅을 구축할 수 있는 go_router 패키지에 대해서 알아보겠습니다.

go_router

go_router는 URL을 기반으로 라우팅, 딥 링크를 핸들링할 수 있게 해주는 Flutter용 라우팅 패키지입니다.

go_rotuer를 왜 사용할까?

go_router 패키지 공식문서에서는 아래와 같은 기능을 간편하게 제공한다고 합니다.

  • 템플릿 구문(예: "user/:id')을 사용하여 경로 및 쿼리 매개변수 구문 분석
  • 목적지에 대한 여러 화면 표시(하위 경로)
  • 리다이렉션 지원
  • ShellRoute를 통한 여러 Navigator 지원
  • Material 및 Cupertino 앱 모두 지원
  • Navigator API와의 하위 호환성

1. 쿼리 매개변수

go_router는 웹 서버처럼 URL기반으로 라우팅을 처리합니다. 기존의 Navigator는 라우팅되는 위젯을 반환하거나 혹은 named navigator를 이용하여 라우팅을 관리하였습니다. URL을 기반으로 라우팅을 제공하니 URL상에서의 쿼리 매개변수같은 것들을 라우팅 위젯에 간단하게 제공할 수 있게 해줍니다.

2. 하위 경로

Navaigator는 하위 경로에 개념이 존재하지 않았습니다. 그저, 하위 경로를 개발자가 직접 코드로 작성하였죠. 그렇다보니 여러 라우팅기법을 사용하며 화면을 탐색하거나 뒤로가기를 적용시켜왔습니다. 하지만, go_router를 통해서 하위 경로를 지정할 수 있으니, 라우팅을 통해 두개 이상의 화면을 제공할 수 있습니다.

3. 리다이렉션

로그인상태에 따라서 사용자는 로그인 화면 혹은 메인 화면에 위치해야겠죠? go_router를 통해서 이러한 리다이렉션을 제공할 수 있습니다.

4. ShellRoute

중첩 라우팅처럼 화면의 특정 부분에서 하위 UI로 전환되어야 되는 경우 복잡한 작업이 필요했지만, go_router에서는 ShellRoute를 이용하여 중첩 라우팅을 구성할 수 있습니다.

여기까지 알아보고 이제 사용하는 방법에 대해서 알아보겠습니다.

go_router 시작하기

go_router를 사용하기 위해서는 패키지를 설치해야 합니다.

$ flutter pub add go_router

위 명령어를 통해 패키지를 설치합니다.

class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(
        child: Text("Hello!"),
      ),
    );
  }
}

위 코드는 HomeScreen의 UI입니다. 가운데에 Hello! 라는 글자가 랜더링 될 것입니다.

이제 go_router를 이용하여 HomeScreen을 초기 화면으로 설정해봅시다. 그러기 위해서는 router를 정의해야 합니다.

final router = GoRouter(
	routes: [
  		GoRoute(
    		path: "/",
    		builder: (context, state) => const HomeScreen(),
  		),
	]
);

router를 통해 "/" 경로에 해당하는 HomeScreen을 지정했습니다. 경로는 GoRoute를 통해 지정할 수 있으며, 경로에 해당하는 path, 라우팅되는 UI인 builder를 통해 하위 UI를 반환해야 합니다.

이제 이를 MaterialApp에 지정하면 됩니다.

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
    );
  }
}

MaterialApp에 router를 이용할 수 있게끔 router가 지정되어 있습니다. 이를 선언한 후, routerConfig에 우리가 선언한 route를 정의하면 됩니다.

여러 화면 지정

여러개의 화면을 사용한다면 route에 사용하고자하는 GoRoute를 추가하면 됩니다.

final router = GoRouter(routes: [
  GoRoute(
    path: "/",
    builder: (context, state) => const HomeScreen(),
  ),
  GoRoute(
    path: "/second",
    builder: (context, state) => const SecondScreen(),
  ),
]);

위 경우에는 "/" 경로가 우선하여 초기 UI로 지정되지만, 만약 "/second" 경로를 초기 UI로 지정하고 싶다면, initailLocation에 해당 경로의 URL을 지정하면 됩니다.

final router = GoRouter(initialLocation: "/second", routes: [
  GoRoute(
    path: "/",
    builder: (context, state) => const HomeScreen(),
  ),
  GoRoute(
    path: "/second",
    builder: (context, state) => const SecondScreen(),
  ),
]);

매개변수와 쿼리 파라미터

URL을 이용하면 매개변수와 쿼리 파라미터를 이용할 수 있습니다. 매개변수에는 어떻게 접근할 수 있을까요? SecondScreen은 userId를 전달받아 화면 중앙에 랜더링 시켜보겠습니다.

class SecondScreen extends StatelessWidget {
  final String userId;
  const SecondScreen({super.key, required this.userId});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Text(userId),
      ),
    );
  }
}

이제, path에 매개변수접근을 위하여 아래와 같이 경로를 지정합니다.

final router = GoRouter(initialLocation: "/second/1234", routes: [
  GoRoute(
    path: "/",
    builder: (context, state) => const HomeScreen(),
  ),
  GoRoute(
    path: "/second/:userId",
    builder: (context, state) =>
        SecondScreen(userId: state.pathParameters["userId"]!),
  ),
]);

이로써, path를 통해 매개변수를 전달받을 수 있습니다. 이번에는 쿼리 파라미터를 이용해볼까요? 쿼리 파라미터는 path는 변경할 필요없이 이동시에 URL에 쿼리 파라미터를 지정하면 됩니다.

final router = GoRouter(initialLocation: "/second?userId=1234", routes: [
  GoRoute(
    path: "/",
    builder: (context, state) => const HomeScreen(),
  ),
  GoRoute(
    path: "/second",
    builder: (context, state) =>
        SecondScreen(userId: state.uri.queryParameters["userId"]!),
  ),
]);

이로써, 매개변수와 쿼리 파라미터를 이용한 라우팅에 대해서 알아보았습니다.

페이지 라우팅

이제 go_router를 통한 페이지 라우팅에 대해서 알아보겠습니다.

1. 화면 전환

context.go는 새로운 화면으로 전환하는 메소드입니다.

context.go("/second?userId=1234");

이는 push가 아니라 새로운 화면으로 전환되므로 뒤로가기는 제공되지 않습니다.

2. push

push 방식은 말 그대로 push 메소드를 이용하면 됩니다.

context.push("/second?userId=1234");

Naviagator의 push 메소드처럼 뒤로가기를 제공합니다.

3. pop

pop은 페이지 스택에서 현재 페이지를 제거합니다. 이를 통해 뒤로가기를 구현할 수 있습니다.

context.pop();

하위 경로

go_router는 하위 경로를 제공한다고 했습니다. 하위 경로를 지정할 때는 GoRoute 내부에 routes에 경로를 추가해주면 됩니다. 이 경우에 하위 경로는 /를 붙이지 않고 지정해주면됩니다.

final router = GoRouter(initialLocation: "/", routes: [
  GoRoute(path: "/", builder: (context, state) => const HomeScreen(), routes: [
    GoRoute(
        path: "second",
        builder: (context, state) =>
            SecondScreen(userId: state.uri.queryParameters["userId"]!),
        routes: [
          GoRoute(
            path: "third",
            builder: (context, state) => const ThirdScreen(),
          ),
        ]),
  ]),
]);

이제 아래와 같은 코드로 한번에 ThirdScreen으로 이동할 수 있습니다.

context.go("/second/third")

ShellRoute와 리다이렉션은 다음에 또 다루도록 하겠습니다.

profile
자기주도적, 지속 성장하는 모바일앱 개발자가 되기 위해

0개의 댓글