강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

dlwjdgus3217님의 프로필 이미지
dlwjdgus3217

작성한 질문수

리액트 포트폴리오 로그아웃 기능 질문

작성

·

214

0

안녕하세요.

graphql에서 로그인 기능을 이용하였습니다. 로그인을 하면 위에 레이아웃 header부분에 user의 이름과

로그아웃 버튼이 입력되어 있습니다.



export default function MainPage(): JSX.Element {
  const [, setAccessToken] = useRecoilState(accessTokenState);
  const [, setIsLogin] = useRecoilState(isLoginState);
  const [loginUser] = useMutationLoginUser();
  const router = useRouter();

...

  const onClickSubmit = (data: IFormData): void => {
    console.log(data);
    void login(data);
  };

  const login = async (data: IFormData): Promise<void> => {
    const result = await loginUser({
      variables: {
        email: data.email,
        password: data.password,
      },
    });
    const accessToken = result.data?.loginUser.accessToken;
    if (accessToken === undefined) {
      alert("로그인실패");
      return;
    }
    setAccessToken(accessToken);
    // localStorage.setItem("accessToken", accessToken); // 임시저장
    console.log(accessToken);
    setIsLogin(true);
    void router.push("/boards/list");
  };

 ...

위 코드는 로그인을 할 때 코드이며 setAccessToken을 이용하여 토큰을 집어넣고 setIsLogin을 이용하여 로그인 상태를 true로 바꿉니다.

 


export default function LayoutHeader(): JSX.Element {
  const router = useRouter();
  const [logoutUser] = useMutationLogoutUser();
  const [accessToken, setAccessToken] = useRecoilState(accessTokenState);
  const [isLogin, setIsLogin] = useRecoilState(isLoginState);
  const [userName, setUserName] = useRecoilState(accessTokenUserName);

  const { data } =
    useQuery<Pick<IQuery, "fetchUserLoggedIn">>(FETCH_USER_LOGGED_IN);
  if (data !== undefined) {
    setUserName(data.fetchUserLoggedIn.name);
  }

  const onClickLogo = (): void => {
    void router.push("/boards/list");
  };

  const onClickLogin = (): void => {
    void router.push("/main");
    console.log(userName);
  };


  const onClcikLogout = async (): Promise<void> => {
    await logoutUser();
    setAccessToken("");
    setIsLogin(false);
    setUserName("");
    console.log(accessToken);
    console.log(isLogin);
  };

다음은 레이아웃 header부분의 코드입니다. 데이터를 받아와 userName에 useRecoilState를 사용하여 저장합니다. 로그아웃 버튼을 누르면 setAccessToken, setUserName을 이용하여 공란을 만듭니다. setIsLogin을 이용하여 login상태를 false로 변경합니다. 그럼 분명히 userName이 없어져야 하는데

 

로그아웃 버튼을 누르고 다시 로그인하기를 눌러도 console.log(userName);을 해보면 aaaa라고 나옵니다. 다시 재차 로그인을 이름이 aaaa가 아닌 다른 아이디로 해보아도

 

3333이란 이름이 나와야 하는데

 

aaaa로 나옵니다. 혹시 이유가 뭔지 알 수 있을까요?

 

주소창에 주소를 다시 입력하고 로그인하면 새롭게 적용이 잘 됩니다. 하지만 동적라우팅으로만 했을 시 적용이 되지 않습니다.

답변 1

0

안녕하세요 dlwjdgus3217님, 인프런 AI 인턴이에요.

해당 문제를 해결하기 위해선 두 가지가 확인되어야 합니다.

  1. 로그아웃 이후에도 상태가 바뀌지 않는 이유

  2. 동적 라우팅시 적용되지 않는 이유

  3. 로그아웃 이후에도 상태가 바뀌지 않는 이유:
    문제를 확인하기 위해 코드를 살펴봤는데, setUserName(data.fetchUserLoggedIn.name); 이 부분에서 원하는 대로 userName 상태가 업데이트되지 않는 것 같습니다. 이는 useQuery 훅의 동작 시점 때문일 수 있습니다. useQuery 훅은 컴포넌트 렌더링 단계에서 데이터를 로딩하고 상태를 업데이트하는 역할을 하기 때문에, 이 시점에서 userName 상태가 업데이트되지 않을 수 있습니다. 이를 해결하기 위해서는 useQuery 훅 대신에 useLazyQuery 훅을 사용하여 명시적으로 데이터를 요청하고 업데이트하는 방법이 있습니다.

  4. 동적 라우팅시 적용되지 않는 이유:
    동적 라우팅으로 주소를 변경하는 경우, 컴포넌트가 새로 마운트되는 것이 아니기 때문에 컴포넌트의 상태가 초기화되지 않을 수 있습니다. 해결 방법으로는, useEffect 훅을 사용하여 동적 라우팅 파라미터의 변경을 감지하고 상태를 업데이트하는 로직을 구현하는 것이 있습니다. useEffect 훅의 의존성 배열에 변경을 감지할 변수를 넣어주면 됩니다.

위의 두 가지 문제에 대해 해결 방법을 설명드렸는데, 실제로 코드를 실행해보지 않아서 문제점을 정확히 파악하기 어려워 더 자세한 도움을 드리기 힘들 수 있습니다. 만약 추가적인 도움이 필요하시면 코드의 전체적인 흐름을 포함하여 문제를 더 자세히 설명해주시면 더 정확한 도움을 드릴 수 있을 것입니다. 감사합니다.

dlwjdgus3217님의 프로필 이미지
dlwjdgus3217

작성한 질문수

질문하기