* 해당 글은 go_router 13.0.1 버전으로 설명되어 있습니다.
* 버전이 업데이트되면서 바뀌는 사항은 하단에 업데이트되어 있습니다.
우리가 흔히 사용하는 웹상의 주소를 살펴보면 빨간색 영역이 도메인 영역 파란색은 path Parameter 초록색 영역은 queryString 영역입니다. 앱에서도 이처럼 pathParameter와 queryString을 이용해서 라우팅 관리를 할 수 있습니다. go_router를 이용해서 pathParameter와 queryString을 다루어 보겠습니다.
1. path Parameter
path(길, 경로) 즉 이동하고 싶은 길이나 경로를 정해줘야 합니다.
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return SchoolPage();
},
),
GoRoute(
path: '/student/:id',
builder: (context, state) {
return StudentPage(state.pathParameters['id']);
},
),
],
);
(SchoolPage 코드)
final studentIdList = [14, 37];
class SchoolPage extends StatelessWidget {
const SchoolPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: studentIdList.map((e) {
return ElevatedButton(
onPressed: () {
context.push('/student/$e');
},
child: Text(e.toString()),
);
}).toList(),
),
);
}
}
(StudentPage 코드)
class StudentPage extends StatelessWidget {
const StudentPage(this.id, {super.key});
final String? id;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: id == null ? Text("없는 학생입니다.") : Text("$id 학생입니다."),
),
);
}
}
이제 익숙한 코드이죠? 이렇게 앱을 실행시키면 path가 ' / ' 인 SchoolPage가 실행될 것입니다.
GoRoute(
path: '/student/:id',
builder: (context, state) {
return StudentPage(state.pathParameters['id']);
},
),
이제 해당코드를 보면 path에 : 콜론이 붙어 있는 것이 확인됩니다. go_router에서 pathParameter를 설정하면 : (콜론)을 붙여주어야 합니다. 콜론 뒤에 이름은 자유롭게 지어도 됩니다. (변수 느낌)
context.push('/student/$e');
SchoolPage에서 해당 코드가 실행되면 ' /student/ ' 뒤에 붙은 e (id)가 :id로 설정해 둔 pathParameter로 들어가게 됩니다.
그리고 StudentPage에 해당 id를 넘겨서 StudentPage로 이동하게 됩니다.
이때 코드를 보시면 처음으로 state라는 것을 이용했는데요 해당 state는 너무 다양한 것들이 있어서 다음글에 자세히 알아보고 이번글에서 사용한 코드에 대해서 알아보겠습니다.
state.pathParameters['id']
state는 쉽게 go_router를 이용해서 무언가를 했을 때 그 무언가에 대한 상태라고 생각해 주세요. 우리는 context.push('/student/$e'); 를 go_router를 이용해서 하였으니 state에는 이 동작에 대한 상태가 있다고 가정하고 위 코드를 보면 state에 pathParameters ['id']
id로 설정한 pathParameters에서 무언갈 가져오는 것입니다.
GoRoute(
path: '/student/:id',
builder: (context, state) {
return StudentPage(state.pathParameters['id']);
},
),
우리는 해당 코드에서 : (콜론) 뒤에 id로 설정한 path를 설정해 두었죠?
context.push로 '/student/$e' -> '/student/14'라고 한다면 14가 id에 key-value 형태로 들어가게 됩니다.
그래서 state.pathParameters ['id'] 코드를 실행하면 14가 반환되게 됩니다. 그러면 StudentPage에 14라는 값을 넘기면서 페이지를 이동하게 되는 꼴이지요.
(전체 예시 코드)
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router,
title: 'go_router',
);
}
}
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return SchoolPage();
},
),
GoRoute(
path: '/student/:id',
builder: (context, state) {
return StudentPage(state.pathParameters['id']);
},
),
],
);
final studentIdList = [14, 37];
class SchoolPage extends StatelessWidget {
const SchoolPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: studentIdList.map((e) {
return ElevatedButton(
onPressed: () {
context.push('/student/$e');
},
child: Text(e.toString()),
);
}).toList(),
),
);
}
}
class StudentPage extends StatelessWidget {
const StudentPage(this.id, {super.key});
final String? id;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: id == null ? Text("없는 학생입니다.") : Text("$id 학생입니다."),
),
);
}
}
2. query String
query String은 위에 사진에서? 뒤에 있는 연두색 영역입니다. key-value로 형식으로 이루어져 있고 & 로 구분합니다. path는 정확하게 해당 path로 이동해야 되지만 query String은 path로 이동한 페이지에서 query가 있으면 참조하는 느낌이라 없으면 없는 대로 있으면 있는 대로 처리할 수 있습니다. 약간 필터느낌이라고 생각할 수 있습니다.
SchoolPage에서 pathParameter를 사용할 때는 context.push('/student/&e')를 이용했다면 queryString 사용법은
context.push('/student?id=$e');
이동할 path 뒤에 ?로 queryString을 알리고 원하는 키(id)에 값을 넣어 전달하면 됩니다.
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return SchoolPage();
},
),
GoRoute(
path: '/student',
builder: (context, state) {
return StudentPage(state.uri.queryParameters['id']);
},
),
],
);
goRouter설정에서는 pathParameter에서는 /student/:id로 path를 설정했다면 queryString은 기본 path만 적어주면 됩니다.
하지만 queryString은 state에서 받아오는 방법이 다릅니다. state.uri로 접근해서 queryParameters에 아까 정한 키로 받아올 수 있습니다. 이렇게 해서 실행해 보면 됩니다.
(전체 예시 코드)
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router,
title: 'go_router',
);
}
}
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return SchoolPage();
},
),
GoRoute(
path: '/student',
builder: (context, state) {
return StudentPage(state.uri.queryParameters['id']);
},
),
],
);
final studentIdList = [14, 37];
class SchoolPage extends StatelessWidget {
const SchoolPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: studentIdList.map((e) {
return ElevatedButton(
onPressed: () {
context.push('/student?id=$e');
},
child: Text(e.toString()),
);
}).toList(),
),
);
}
}
class StudentPage extends StatelessWidget {
const StudentPage(this.id, {super.key});
final String? id;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: id == null ? Text("없는 학생입니다.") : Text("$id 학생입니다."),
),
);
}
}
3. 추가 예제 코드
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router,
title: 'go_router',
);
}
}
final router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) {
return SchoolPage();
},
),
GoRoute(
path: '/school/:route',
builder: (context, state) {
if (state.pathParameters['route'] == "info") {
return SchoolInfoPage();
}
return StudentPage(state.uri.queryParameters['id']);
},
),
],
);
class SchoolPage extends StatelessWidget {
const SchoolPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
onPressed: () {
context.push('/school/info');
},
child: Text("학교 소개 페이지"),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
context.push('/school/student?id=1');
},
child: Text("1번 학생 페이지"),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
context.push('/school/student?id=2');
},
child: Text("2번 학생 페이지"),
),
],
),
);
}
}
class SchoolInfoPage extends StatelessWidget {
const SchoolInfoPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(child: Text("주톨 대학교 입니다.")),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
context.pop();
},
child: Text("돌아가기"),
),
],
),
);
}
}
class StudentPage extends StatelessWidget {
const StudentPage(this.id, {super.key});
final String? id;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Center(child: Text(id != null ? "$id번 학생 입니다." : "없는 학생 입니다.")),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
context.pop();
},
child: Text("돌아가기"),
),
],
),
);
}
}
해당 코드를 복사해서 실행해보고 코드 구조를 살펴보면 이해가 되실 겁니다.
'Flutter > GoRouter' 카테고리의 다른 글
[Flutter] go_router - 3 : push, pop 페이지 이동 (0) | 2024.01.12 |
---|---|
[Flutter] go_router - 2 : 초기 페이지 설정 (0) | 2024.01.11 |
[Flutter] go_router - 1 : 프로젝트 적용 (0) | 2024.01.10 |