본문 바로가기

[flutter,beamer] beamer 대신 go_router로 guard pages 구현

ironwhale 2022. 7. 28.

1. beamer 1.3 이후 버전 사용시 stackoverflow 에러발생

 아마도 이 에러가 나시는 분은 1.3 이상의 최신  beamer를 사용하시면서 beamGuard의 showpage를 사용하시는 분일거 같습니다. 

 

 flutter에는 navigator 2.0을 쉽게 구현할 수 있도록 beamer라는 라이브러리가 있는데 이 최신 버전의 beamer 사용하시는 분들이 BeamGuardshowpage를 사용하면 stackoverflow 에러 메시지를 만나실 것입니다.

그래서 beamer 제작자 분께 직접 문의를 드려서 이렇게 하면 된다고 답변도 받았는데 간단한 코드가 더 어려워 져서 결국 beamer사용은 잠시 접어두고 go_router로 전환해보려고 합니다.

목차


    2. go_routerBeamGuard (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로 화면 이동 구현하기 (로그인 가드 구현 포함)

     

    [Flutter] - go_router로 화면 이동 구현하기 (로그인 가드 구현 포함)

    go_router는 페이지 이동을 위한 플러터 패키지 고라우터(go_router)는 플러터(flutter)의 화면 전환을 위한 패키지 입니다. 예를 들어 초기 화면에서 어떤 버튼을 누르면 글쓰기 페이지로 이동하는 기

    jh-industry.tistory.com

     

    2022.08.14 - [flutter] 코딩파파 당근마켓 클론 코딩 강좌 공부 - Beamer에서 Go_Router로 전환

     

    [flutter] 코딩파파 당근마켓 클론 코딩 강좌 공부 - Beamer에서 Go_Router로 전환

    Beamer Stackoverflow 에러 발생 코딩파파 당근마켓 클론코딩을 공부하다 보면 대부분의 사람들이 막히는 부분이 있습니다. 바로 beamer를 사용하는 부분일것입니다. 1.2버전까지는 코딩파파님의 강의

    jh-industry.tistory.com

     

    댓글