• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

상위/하위 redirect 후 반응

23.10.12 18:20 작성 23.10.12 18:33 수정 조회수 159

0

안녕하세요 선생님.
다름이 아니라 강의를 듣다가 강의 마지막쯤에

GoRoute의 상위에서 redirect를 작성할 때와, routes안에 GoRoute(이하 하위)에서 redirect 할 때의 차이점을 설명해주셨는데요.

그래도 눈으로 확인하고 싶어서 print()를 통해 디버깅하고자 아래와 같은 코드로 작성한 상태입니다.

코드 -> 질문 순서로 하겠습니다.

// 불필요한 코드는 임의로 삭제하겠습니다.


import ...

bool authState = false;


final router = GoRouter(

  redirect: (context, state) {
    print(state.location);
    print('상위 redirect');

   ...
  },
  routes: [
        ...
        GoRoute(
          path: 'login2',
          builder: (_, state) => LoginScreen(),
          routes: [
            GoRoute(
              path: 'private',
              builder: (_, state) => PrivateScreen(),
              redirect: (context, state) {
                print(state.location);
                print('하위 redirect');
                if(!authState) {
                  return '/login2';
                }
                return null;
              },
            ),
          ],
        )
      ],
    ),
  ],
);

작성한 코드는 이러합니다.

  • 상위에서 print문을 2번 사용해서 현재 위치와 상위redirect임을 밝힙니다.

  • 하위에서 마찬가지로 print문을 2번 사용해서 현재 위치와 하위redirect임을 밝힙니다.

     

     

    여기서부터 궁금한게 여러가지 생겼습니다.

     


    login에 실패하여 /private으로 가지 못하는 상황입니다.

     

     

    제가 생각했던 출력문은

  • 상위에서는

    I/flutter (20444): /login/private
    I/flutter (20444): 상위 redirect
    

    이렇게 출력될 것이다 생각했는데 아래와 같이 나왔습니다.

    I/flutter (20444): /login/private
    I/flutter (20444): 상위 redirect
    I/flutter (20444): /login
    I/flutter (20444): 상위 redirect

    Q1. 이렇게 나오는 이유가 authState값을 모르는 채로 /private에 진입부터 했다가 (=출력문 1번), false값인걸 확인하고 /login으로 다시 돌아와서 출력문 3번이 나온것이 맞는지 궁금합니다.




    또한 하위 redirect에서 질문이 있습니다.
    먼저한 질문(Q1)이 맞다면 , 예상했던 출력값이 있습니다.

    예상출력값)

    I/flutter (20444): /login2/private
    I/flutter (20444): 하위 redirect
    I/flutter (20444): /login2
    I/flutter (20444): 하위 redirect

 

그러나 실제로 출력결과는 아래와 같았습니다.

  •  

    I/flutter (20444): /login2/private
    I/flutter (20444): 상위 redirect
    I/flutter (20444): /login2/private
    I/flutter (20444): 하위 redirect
    I/flutter (20444): /login2
    I/flutter (20444): 상위 redirect

 

상위는 /private에 갔다가 /login으로 돌아오는게 출력된 반면, 하위는 /private에 갔다가 돌아오는 출력문이 찍히지를 않았습니다.

Q2. 그렇다면 왜 이렇게 출력되는지 플로우나 실행흐름 같은게 궁금합니다.

또한 상위와 하위 redirect가 무조건적으로 동시에 실행하게 된다면, 상위의 redirect는 하위의 redirect로 덮어쓰여져서 하위만을 실행하거나 하위 우선적인 로직이 수행하는지 궁금합니다.

 

감사합니다 X)

 

답변 1

답변을 작성해보세요.

1

안녕하세요!

질문 해주신 내용에서 언급하신 숫자들이 제가 보고있는 내용과 조금 달라서 의문 가시는 부분을 제가 정확히 이했는지는 잘 모르겠으나 궁금하실만한 부분을 유추 해가면서 답변 드리도록 하겠습니다.

일단 첫번째로 저희가 정립하고 가야하는건 /login 스크린과 /login2 스크린은 현재 라우팅이 매우 다르게 돼있습니다.

/login의 경우 상위 redirect에 '로그인이 되지 않은 상황에' 조건에 걸리도록 설정돼있고 /login2는 그렇지 않습니다.

제가 똑같은 테스트를 해본 결과 /login에서 로그인을 하지 않은 상태로 'Go to Private Route'를 누르게 되면 아래와 같은 출력이 나옵니다.

 

flutter: 상위 redirect

flutter: /login/private

flutter: 상위 redirect

flutter: /login

 

여기서 중요한건 제가 redirect에 대해서 강조드렸던 부분을 기억 하셔야합니다. redirect는 화면 이동에 대한 명령이 실행 됐을때 실제 화면 전환이 이루어지기 전에 실행되는 로직입니다. 그렇기 때문에 redirect에서 화면 전환에 대한 로직을 변경하게 되면 실제 요청한 화면으로 이동하기 전에 다른 화면으로 이동하도록 할 수 있습니다.

첫번째 출력된 상위 redirect의 경우 /login/private으로 이동을 실제로 요청했기 때문에 출력된 값입니다.

두번째 출력은 /login/private으로 이동하려다가 /login으로 redirect가 됐기 때문에 이동되기 전에 '또' 실행된 로직입니다. 저희가 redirect에서 다른 라우트를 반환 했다는 뜻은 해당 라우트가 라우트 스택에 올라와있던 올라와 있지 않던 해당 화면으로 '이동' 하라는 명령이니까요.

 

다음으로는 login2를 봐보겠습니다.

 

flutter: 상위 redirect

flutter: /login2/private

flutter: 하위 redirect

flutter: /login2/private

flutter: 상위 redirect

flutter: /login2

 

/login과 크게 다르지 않지만 하나의 출력이 더 있습니다. 그 이유는 간단합니다. redirect는 상위부터 적용되고 하위로 내려옵니다. 논리적으로 생각해보면 당연히 그래야 할 거라고 생각 될 수밖에 없습니다. 로직을 점점 좁혀나가는게 논리적일 테니까요. 그래서 /login2/private으로 이동할때 상위 redirect가 먼저 불립니다. 상위 redirect에서 null이 반환되기 때문에 다음 redirect인 하위 redirect가 불립니다. 여기서 null 반환이 아닌 또다른 화면으로 전환을 시켜버렸기 때문에 전환된 화면을 기반으로 redirect가 다시 실행됩니다. (이 부분은 위에서 설명한 것과 같습니다.) 상위 redirect에서 null이 반환되고 하위 redirect는 존재하지 않기 때문에 여기서 로직은 멈춥니다.

도움 되는 설명이었길 바랍니다.

감사합니다!

 

P.S /login2 화면에서 말씀하신대로 두번째 하위 redirect가 불릴 수 없는 이유는 하위 redirect가 적용된 위치를 다시 봐보시면 쉽게 알 수 있습니다.

dugong.yul님의 프로필

dugong.yul

질문자

2023.10.13

이해했습니다 감사합니다 :)