[flutter,beamer] beamer 대신 go_router로 guard pages 구현
1. beamer 1.3 이후 버전 사용시 stackoverflow 에러발생
아마도 이 에러가 나시는 분은 1.3 이상의 최신 beamer를 사용하시면서 beamGuard의 showpage를 사용하시는 분일거 같습니다.
flutter에는 navigator 2.0을 쉽게 구현할 수 있도록 beamer라는 라이브러리가 있는데 이 최신 버전의 beamer 사용하시는 분들이 BeamGuard와 showpage를 사용하면 stackoverflow 에러 메시지를 만나실 것입니다.
그래서 beamer 제작자 분께 직접 문의를 드려서 이렇게 하면 된다고 답변도 받았는데 간단한 코드가 더 어려워 져서 결국 beamer사용은 잠시 접어두고 go_router로 전환해보려고 합니다.
2. go_router로 BeamGuard (showpage)기능 구현하기
아래 코드와 같이 간단한 로그인 로그아웃 페이지를 구현해보았습니다.
필요한 패키지
- provider: ^6.0.3
- go_router: ^4.2.2
프로바이더로 로그인 상태관리를 하는 코드입니다.
로그인이 되있으면 HomePage()로 안되어 있으면 ForbiddenPage() 가는 코드 입니다.
핵심적인 부분
beamer의 BeamerDelegate, BeamLocation 부분이 하나로 GoRouter로 처리하는 더욱 간편해 진 느낌입니다.
final _router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => const HomePage()),
GoRoute(path: '/forbidden', builder: (context, state) => const ForbiddenPage())
],
redirect: (GoRouterState state) {
final loggedIn = userNotifier.userStatus;
final loggingIn = state.subloc == '/forbidden';
if (!loggedIn) {
logger.d("!loggedIn,${!loggedIn}");
return loggingIn ? null : '/forbidden';
}
if (loggingIn) {
logger.d("!/, ${!loggingIn}");
return '/';
}
// logger.d("null");
// return null;
},
refreshListenable: userNotifier);
전체코드
import 'package:beamer_train/logger.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
class ForbiddenPage extends StatelessWidget {
const ForbiddenPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Forbidden Page"),
),
body: Center(
child: TextButton(
onPressed: () {
context.read<UserNotifier>().changeStatus(true);
},
child: const Text("login", style: TextStyle(fontSize: 30)),
),
),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Home Page"),
),
body: Center(
child: TextButton(
onPressed: () {
context.read<UserNotifier>().changeStatus(false);
},
child: const Text("logout", style: TextStyle(fontSize: 30)),
),
),
);
}
}
class UserNotifier extends ChangeNotifier {
bool _userStatus = false;
void changeStatus(bool status) {
_userStatus = status;
notifyListeners();
}
bool get userStatus => _userStatus;
}
void main() {
runApp(MyApp());
}
final userNotifier = UserNotifier();
final _router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => const HomePage()),
GoRoute(path: '/forbidden', builder: (context, state) => const ForbiddenPage())
],
redirect: (GoRouterState state) {
final loggedIn = userNotifier.userStatus;
final loggingIn = state.subloc == '/forbidden';
if (!loggedIn) {
logger.d("!loggedIn,${!loggedIn}");
return loggingIn ? null : '/forbidden';
}
if (loggingIn) {
logger.d("!/, ${!loggingIn}");
return '/';
}
// logger.d("null");
// return null;
},
refreshListenable: userNotifier);
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<UserNotifier>.value(
value: userNotifier,
child: MaterialApp.router(
routeInformationProvider: _router.routeInformationProvider,
routerDelegate: _router.routerDelegate,
routeInformationParser: _router.routeInformationParser,
),
);
}
}
다른 go_router 관련 포스팅 링크 입니다.
2023.03.23 - [Flutter] - go_router로 화면 이동 구현하기 (로그인 가드 구현 포함)
2022.08.14 - [flutter] 코딩파파 당근마켓 클론 코딩 강좌 공부 - Beamer에서 Go_Router로 전환
댓글