MainLayout

MainLayout의 전체 코드. 간단하다.

전체 코드는 작지만, 모르는 부분이 있었다. children.

MainLayout({ children }) 이란,

<div /> 안에 있는 { children } 은 모든 자식 요소들을 가져와서 사용할 수 있다. 그럼 MainLayout의 CSS부분을 적용해 놓으면 그 하위에 있는 모든 자식 요소들에게 적용할 수 있다는 것이다.

App.js파일의 한 부분.

App.js파일에 보면 <MainLayout />안에 있는 모든 라우터들이 있다.

 

<MainLayout>이 최상위 부모 컴포넌트가 되고, { children }을 통해 <Routes>와 그 안의 <Route>들이 모두 들어간다. 그리고 그 Route들이 각각의 Page등을 렌더링 할 수 있다.

 

Mainheader

import { Link, Navigate, useNavigate } from 'react-router-dom'; 에 관한 설명이다.

 

Link: 페이지 이동을 위한 컴포넌트.

Navigate: 특정 경로로 리디렉트할 때 사용.

*리디렉트(Redirect)는 사용자가 요청한 URL이 아닌 다른 URL로 보내는 것을 의미

useNavigate: 프로그래밍 방식으로 페이지 이동할 때 사용.

 

import { accessTokenAtomState, authUserIdAtomState } from '../../atoms/authAtom';

accessTokenAtomState, authUserIdAtomState: 사용자 인증 관련 전역 상태를 의미한다.

 

import { useQuery, useQueryClient } from 'react-query';

useQuery()를 사용해서 데이터를 가져오고,

useQueryClient()를 사용해서 캐시를 조작할 수 있음.

 

TMI: import도 색깔이 연한 부분은 사용하지 않는 부분이다. 없앨 수도 있지만, 없애지 않아도 별로 상관없다.

그럼에도 에러가 난다면 연한 부분은 없애면 될 일이다.

 

useEffect - 컴포넌트가 렌더링될 때 실행되는 함수 이다. API요청, 이벤트 리스너 등록, 타이머 설정 등 비동기 작업을 수행할 때 사용한다.

 

useState - 상태 값 관리

useSetRecoilState는 MainHeader에서

const setAccessToken = useSetRecoilState(accessTokenAtomState) 함수가 있는데

Atom은 전역상태, Recoil은 업데이트이므로 전역상태의 토큰을 업데이트 한다고 할 수 있다.

 

 

그 전에도 한 번 설명했던것 같은데 다시 설명하자면,

getUserApi 는 url(http://localhost:8080/servlet_study_war/api/user)로 요청을 보내고 로컬 스토리지에서 저장된 AccessToken을 가져와 Bearer 방식으로 헤더에 포함시킨다. 이 토큰을 통해 서버는 요청한 사용자가 인증된 사용자임을 확인할 수 있다.

 

params는 URL에 추가적인 정보를 전달하는 쿼리 파라미터를 설정한다.

예를 들어, http://localhost:8080/servlet_study_war/api/user?userId=12345방식으로 쓸 수 있으며, 

params를 사용함으로써, userId 값을 URL에 포함시켜서 서버가 해당 사용자의 정보를 처리하도록 할 수 있다.

그러나, 아직 값을 넣지 않았기 때문에 undefined는 나오지 않는다.

 

useQuery라는 훅 함수이다.

이 함수는 userId가 있을 때 작동과, 없을 때 작동이 된다.

userId가 없을 때, enabled: false로 설정되어 있으므로, getUserApi함수는 호출되지 않고 쿼리는 실행되지 않습니다.

userId가 있을 때, enabled: true로 설정되어, getUserApi함수는 호출되고 해당 userId에 맞는 API요청을 실행한다.

React Query는 데이터가 캐시되기 대문에, 같은 쿼리 키에 대한 데이터는 재요청 없이 캐시된 데이터를 재사용할 수 있다. 만약 userId가 변경되면, 새로운 쿼리 키에 맞춰서 새로운 데이터를 요청하고 캐시가 갱신된다.

 

refetchOnWindowFocus는 사용자가 브라우저 창을 포커스 할 때 자동으로 쿼리를 재요청 하는 것을 방지한다.

enabled: !!userId는 userId가 존재하는 경우에만 쿼리가 실행되며, userId가 null이나 undefined면 쿼리는 비활성화 된다.

}

 

마지막으로 handleLogoutOnClick에 대한 리뷰다.

localStorage.removeItem("AccessToken")을 호출하면 로그인 상태를 나타내는 AccessToken이 로컬 스토리지에서 삭제된다. 이를 통해 사용자가 로그아웃 하게 된다.

 

setAccessToken(localStorage.getItem("AccessToken")) 로그아웃 후에 AccessToken이 삭제 되었으므로, 상태값이 null로 설정되며, 사용자 인터페이스(UI)에서 로그아웃된 상태로 표시된다.

 

queryClient.removeQueries(["authenticatedUserQuery"]) 이 쿼리도 제거함으로써 로그아웃 후 해당 인증 정보가 캐시에서 삭제 되고, 로그아웃 후에는 다시 인증된 사용자 정보를 요청하지 않게 된다.

 

navigate("/signin") 그리고 signin(로그인 화면)으로 이동하게 된다.

 

MainHeader는 로그인 여부에 따라 동적으로 변경되는 헤더 UI를 구성하고, 사용자 정보를 서버에서 가져오며, 로그아웃 기능을 포함하고 있다. React Query를 사용해 데이터를 효율적으로 관리하고, Recoil을 통해 상태를 관리하며, 페이지 전환은 useNavigate를 통해 처리합니다.