프로젝트 내에서 전역 상태관리가 얼마나 필수적인지 깨달은 뒤, 다양한 상태관리 도구들을 익혀두는 것이 좋겠다는 생각을 하였다. 물론 기존에 애용하던 Redux도 좋은 툴인 것은 맞지만, 각 툴들의 장단점을 알고 상황에 맞게 쓰는 것이 좋은 개발자로서의 자세라고 생각하기 때문이다. 그래서 이번에는 React 내장 기능인 ContextAPI에 대해 알아보고 사용하고자 한다.
본래 Redux나 MobX, Recoil과 같은 유용한 상태관리 라이브러리들이 존재하고 잘 쓰이고 있지만, React v16.3 업데이트 이후 Context API가 상당 부분 개선되었기 때문에 충분히 배워둘만 하다고 생각한다.
전체적인 특징은 여타 상태관리 라이브러리들과 크게 다르지 않다.
평소 Redux에 익숙한 편이어서 Context API를 배우는 데 오랜 시간이 걸리지는 않았다.
이 글에서는 reducer는 사용하지 않고 Contex API만 사용하여 단일 상태를 관리하는 방법을 다루려고 한다.
context.js
import { createContext, useState } from 'react';
const currentUserContext = createContext({
currentUser: "",
setCurrentUserHandler: () => {}
});
const UpdateCurrentUser = ({ children }) => {
const [currentUser, setCurrentUser] = useState("")
const setCurrentUserHandler = (user) => setCurrentUser(user)
return (
<currentUserContext.Provider value={{ currentUser, setCurrentUserHandler }}>{children}</currentUserContext.Provider>
)
};
export default UpdateCurrentUser;
export { currentUserContext };
위의 파일은 내가 프로젝트에서 사용했던 것이다. 위 파일을 하나씩 분석해보자.
const currentUserContext = createContext({
currentUser: "", // 전역적으로 관리하려는 상태
setCurrentUserHandler: () => {} // 상태변경에 쓰이는 함수
});
const [currentUser, setCurrentUser] = useState("")
const setCurrentUserHandler = (user) => setCurrentUser(user)
return (
<currentUserContext.Provider value={{ currentUser, setCurrentUserHandler }}>{children}</currentUserContext.Provider>
)
이제 만든 Context를 가져와 사용해보자.
App.js
import React from 'react';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { withAuthenticator } from '@aws-amplify/ui-react';
import WritingPage from './writingPage';
import LandingPage from './landingPage';
import UpdateCurrentUser from './context';
function App() {
return(
<UpdateCurrentUser>
<BrowserRouter>
<Routes>
<Route path="/" element={<LandingPage />} />
<Route path="/writedown" element={<WritingPage />} />
</Routes>
</BrowserRouter>
</UpdateCurrentUser>
)
}
export default withAuthenticator(App);
위의 코드처럼 생성한 UpdateCurrentUser 컴포넌트를 전역 Context를 사용하고 싶은 컴포넌트들을 감싸도록 만들어야 한다. 그렇게 하위 컴포넌트에게 Context를 제공할 수 있다.
function LandingPage() {
const { currentUser, setCurrentUserHandler } = useContext(currentUserContext)
const checkUser = () => {
setCurrentUserHandler(user.username)
}
useEffect(() => {
checkUser()
}, [])
return (
<>
<h1>{currentUser}</h1>
</>
)
}
위의 코드처럼 사용하는데, 이제 하나하나씩 살펴보자.
<br />
```javascript
import React, { useContext, useEffect } from 'react';
import { currentUserContext } from './context';
const { currentUser, setCurrentUserHandler } = useContext(currentUserContext)
setCurrentUserHandler(user.username)
return (
<>
<h1>{currentUser}</h1>
</>
)
지금까지 React 내장 함수인 Context API에 대해서 알아보고, 예제를 통해 간단한 사용법을 익혀보았다. 물론 전역관리가 필요한 상태가 많고 다양해지면 reducer등을 적용하는 것이 좋다.
16.3 버전 이후로 업데이트된 ContextAPI는 여타 라이브러리와 견줄 정도로 좋은 사용성을 보이는 것 같다. 기회가 된다면 적용해보자!!