이번에 진행 중인 프로젝트에서 로그인 여부에 따라서 다르게 렌더링 해야 하는 컴포넌트가 늘어갔다.
로그인 여부를 전달하기 위해서 내가 선택한 방법은 최상단 컴포넌트에서 토큰을 확인해서 변수에 담아두는 방식이었다. 그리고 이 값이 필요한 자식 컴포넌트의 props 값으로 로그인 여부를 전달했다.
이러한 경우에는 A 컴포넌트는 로그인 여부 값이 필요하지 않지만 A 컴포넌트의 자식인 B 컴포넌트에는 그 값이 필요하기 때문에 A 컴포넌트도 로그인 여부 값을 가지고 있어야 한다. 컴포넌트 depth가 깊어 지거나 하면 관리가 복잡해지는 구조를 가지게 될 것이다.
그러다 React의 Context API를 알게되었다. context를 사용하면 데이터를 전역으로 관리하고 사용할 수 있다.
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false)
useEffect(() => {
const cookie = new Cookies()
setIsLoggedIn(cookie.get('auth_token') !== undefined)
}, [])
...
}
기존에는 위와 같이 App에서 쿠키를 가져와서 토큰이 있는지를 검사하고 그 boolean 값을 가지고 있는다.
(프론트단에서 로그인 여부를 쿠키 값으로 확인하는 게 올바른 방식인지 확인이 필요하다..)
그다음에는 아래 코드와 같이 해당 값이 필요한 자식 컴포넌트로 보내준다.
<Routes>
<Route path='/' element={<Home isLoggedIn={isLoggedIn} />}/>
...
</Routes>
Context API 적용하기
import React, { useState } from 'react'
import { useContext } from 'react'
import { Cookies } from 'react-cookie'
const token = new Cookies().get('auth_token')
export const LoginContext = React.createContext(null)
export const LoginProvider = ({ children }) => {
const [isLoggedIn, setIsLoggedIn] = useState(token !== undefined)
const value = {isLoggedIn, setIsLoggedIn}
return <LoginContext.Provider value={value}>{children}</LoginContext.Provider>
}
먼저 context를 사용하기 위해서 createContext를 사용해 LoginContext를 만든다. 기본값은 null로 지정했다. 로그인 여부를 판단하면서 새로운 value가 세팅이 되는데 이때 담기는 값들은 isLoggedIn와 setIsLoggedIn 변수이다.
export const useLoginContext = () => useContext(LoginContext)
다음은 로그인 상태를 업데이트하고 구독할 수 있는 커스텀 훅을 만들었다.
...
import { LoginProvider } from './shared/LoginContext.jsx'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<LoginProvider>
<App />
</LoginProvider>
</React.StrictMode>,
)
그리고 최상단 컴포넌트에서 LoginProvider로 하위 컴포넌트를 감싸준다.
const App = () => {
const {isLoggedIn, setIsLoggedIn} = useLoginContext()
const handleLogout = () => {
setIsLoggedIn(logout())
window.location.reload();
}
이제 위와 같이 useLoginContext를 불러오고 그 안에 들어있는 value를 담아준다. 바로 아래에 handleLogout 함수가 있는데 header부분을 컴포넌트로 나눠주지 않아서 이렇게 처리하게 만들어 놨다. 당연히 이 부분도 컴포넌트화를 진행해야 한다.
<Routes>
<Route path='/' element={<Home />}/>
...
</Routes>
이제는 Home 컴포넌트에게 로그인 여부 값을 전달하지 않아도 된다. Home에서 useLoginContext를 사용하고 그 안에서 값을 구독하면 된다.
Context API로 데이터를 전역에서 관리하는 방법을 배우고 프로젝트에 적용해 보았다. 아직 리팩터링이 필요한 부분이 많다는 걸 다시 알게 되었다. 그리고 로그인, 로그아웃, 회원가입 로직도 만들어둔 LoginContext를 이용하는 방식으로 다시 한번 리팩터링을 진행해야겠다.
Uploaded by N2T
'TIL' 카테고리의 다른 글
프록시 객체란 무엇인가? (0) | 2024.06.04 |
---|---|
[React] helpers와 utils 디렉터리는 어떻게 구분할까? (0) | 2023.11.16 |
프로세스 스케줄링 (0) | 2023.04.11 |
vi 에디터 사용법 정리 (0) | 2022.08.06 |
swap 설치를 통해 ec2 메모리 할당하기 (0) | 2022.08.04 |