import 'package:flutter/material.dart';
import 'package:flutter_blog/_core/constants/theme.dart';
import 'package:flutter_blog/ui/pages/auth/join_page/join_page.dart';
import 'package:flutter_blog/ui/pages/auth/login_page/login_page.dart';
import 'package:flutter_blog/ui/pages/post/list_page/post_list_page.dart';
import 'package:flutter_blog/ui/pages/post/write_page/post_write_page.dart';
import 'package:flutter_blog/ui/pages/splash/splash_page.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
// TODO: 1. Stack의 가장 위 context를 알고 있다.
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
// context가 없는 곳에서 context를 사용할 수 있는 방법
debugShowCheckedModeBanner: false,
home: SplashPage(),
routes: {
"/login": (context) => const LoginPage(),
"/join": (context) => const JoinPage(),
"/post/list": (context) => PostListPage(),
"/post/write": (context) => const PostWritePage(),
},
theme: theme(),
);
}
}
Context가 없는 상황에서의 문제 발생
class ApiService {
static Future<void> login() async {
try {
// 로그인 API 호출
final response = await dio.post('/login');
// 성공했으니 메인 화면으로 이동하고 싶은데...
// Navigator.pushNamed(context, '/post/list'); ← context가 없어요!
} catch (e) {
// 에러 발생시 사용자에게 알리고 싶은데...
// ScaffoldMessenger.of(context).showSnackBar(...); ← context가 없어요!
}
}
}
// 전역에서 접근 가능한 네비게이터 키
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// MaterialApp에 연결
MaterialApp(
navigatorKey: navigatorKey, // ← 여기서 연결!
// ...
navigatorKey 활용 코드로 편리해졌음
class ApiService {
static Future<void> login() async {
try {
final response = await dio.post('/login');
// 이제 context 없이도 네비게이션 가능!
navigatorKey.currentState!.pushNamed('/post/list');
} catch (e) {
// context 없이도 스낵바 표시 가능!
final context = navigatorKey.currentContext!;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('로그인 실패: $e'))
);
}
}
}
Stack의 의미:
- Flutter는 화면을 Stack 구조로 관리합니다
- 새로운 화면을 열면 위에 쌓이고 (push)
- 뒤로 가면 위에서 제거됩니다 (pop)
"가장 위 context"의 의미:
// 화면 스택 예시
[SplashPage] ← 가장 아래 (첫 화면)
[LoginPage] ← 로그인 화면 추가
[PostListPage] ← 메인 화면 추가 (가장 위)
// navigatorKey.currentContext는 현재 보이는 화면의 context
final currentContext = navigatorKey.currentContext!;
// 이것은 현재 사용자가 보고 있는 화면의 context와 동일
// 따라서 어디서든 현재 화면에 대한 작업 가능!'Flutter' 카테고리의 다른 글
| 블로그 프로젝트 - 로그인 폼 상태 관리 (1) | 2025.09.01 |
|---|---|
| 블로그 프로젝트 - 회원가입 폼 상태 관리 (1) | 2025.08.22 |
| 창고 이야기로 배우는 Riverpod 예제 코드 (3) | 2025.08.22 |
| 상태 관리란 뭘까? - riverpod 2.x (1) | 2025.08.22 |
| 블로그 프로젝트 - 데이터 통신을 위한 Repository 만들기 (0) | 2025.08.22 |