그놈의 axios
https://react.vlpt.us/integrate-api/01-basic.html
그놈의 Context API
저는 그만 리덕스가 그리워져버리는 거예요(사실 대부분의 클론 코딩은 리덕스로 진행했다는 게 치명타일 수도.).
그래서 프로젝트 전반에서 들고 있어야 할 state를 context를 통해 Provider 내부의 요소들에 전부 useContext로 가져온다, 는 게 내가 이해한 내용인데. 아무리 봐도 지금 프로젝트에서 그렇게 사용되고 있는 거 같지가 않다. 예시로 올라왔던 프로젝트 코드를 다운 받아서 실행해 보고 난 뒤에 적용했어야 하는 뒤늦은 후회를 하며... 자꾸만 저 세상으로 흘러가고 있는 집중력을 끄집어 내기 위해 포스트를 작성하며 진행해야겠다는 생각이 들었다.
일단 개념부터 정리해야겠다. Context API에 대한 설명은 이미 위에도 있고 다른 사람들도 재탕삼탕하고 육수까지 뻔질나게 우려먹지만 나도 한 번 정도는 재창해 봐야겠다.
React의 상태관리 라이브러리의 대표 주자에 Redux와 Context API 둘을 들 수 있다. 차이라면 redux는 npm install
을 한 번 더 거쳐야 하는 거고, Context API는 React 내부 라이브러리라서 구조 파악으로 사용할 수 있다는 점 및 복잡도 등등.
내가 이해하고 있는 게 맞다면 아무튼 그 상태관리는 프로젝트 전체에서 사용될 요소에 대한 정의가 수시로 바뀐다는 점 때문에 필요한 거다.
지금도 충분히 겪고 있는 문제지만, 내가 사용하고 있는 구직 플랫폼이 어림잡아 다섯 개 정도 된다. 하지만 각각의 플랫폼은 내가 이력서를 따로 업로드 해줘야 하고, 나의 원본 이력서(로컬에 저장돼 있어야만 할 텐데 사실 존재하지 않는 문서)의 변경이 발생하면 또 각각의 플랫폼에다 이력서를 재업로드 해야 한다. 현실에서 그 플랫폼들을 하나로 묶어줄 수 있는 초강력 메타 플랫폼은 존재하지 않지만, 프로젝트 내부에서 정도는 존재할 수 있다. 그 상태관리를 담당해 주는 대표적인 라이브러리가 redux와 context API인 거다. 그리고 당연할 수도 있겠지만, 사실 redux도 context API로 만들어졌다.
<사설이지만 금융의 초강력 상태관리자는 공동 인증서가 존재하겠다. 그마저도 각 금융 플랫폼마다 자사 인증서를 사용해서 간편하게 어쩌구를 주장하고 있다마는.>
끝!
이러고싶다, 정말...
여기부터의 내용은 그놈의 Context API로 공유해 둔 포스트를 기반으로 재해석 했다.
createContext
함수를 통해 context를 사용할 때 필요한 내용들을 정의한다. 호출하면 Provider
(context의 value를 변경하는 컴포넌트)와 Consumer
(context 변화를 감지하는 컴포넌트)를 반환한다. 필요한 파라미터는 defaultValue이며, Provider를 사용하지 않을 때 적용될 기본 값을 정의하게 된다. <이쯤 되니 객체 지향 프로그래밍의 생성자가 생각나기도.>
그래서 나는 oAuth로 인증하게 될 회원에 대한 정보를 가지고 있게 될 context를 MemberContext라고 정의했다. 최초의 MemberContext는 회원이 로그인하지 않은 상태에서 시작될 것이므로 null이다.
//MemberContext.js
import { createContext, useState } from 'react';
// Context에서 관리해줄 상태값과 메소드들을 정의
export const MemberContext = createContext({
state: { member: null },
actions: { setMember: () => {} }
});
// Provider를 render하며 상태값과 메소드들을 전달
export const MemberProvider = ({ children }) => {
const [member, setMember] = useState(null);
const value = {
state: { member },
actions: { setMember }
};
return (
<MemberContext.Provider value = { [value.state, value.actions] }>
{ children }
</MemberContext.Provider>
)
}
export default MemberContext;
<사실 위의 코드는 카우치 코딩에서 제공한 샘플 코드를 위에서 공유한 medium 글의 설명에 맞춰 변형한 형태라 psedo(허위매물)에 가깝다. 실제로 작동하는지는 써봐야 아는 것...>
그렇게 만들어진 Context를 필요한 곳에 배치함으로 자식 컴포넌트들에게 전달되어 전역 변수처럼 쓸 수 있게 된다. Member의 정보와 관련된 부분은 프로젝트 전체에서 필요한 내용이므로 보통은 최상위에 넣게 된다.
//index.js
import React from 'react';
import { MemberProvider } from './component/MemberContext';
import App from './App';
ReactDOM.render(
<MemberProvider>
<App/>
</MemberProvider>, document.getElementById('root')
);
누가 봐도 psedo code
전체에서 이 Context를 사용하기로 했으니 추적하려는 값에 대한 정보를 Context.Consumer
혹은 useContext
를 통해 가져올 수 있다. hook이 더 직관적이기 때문에 useContext
로 추적하도록 하자.
import { useContext } from 'react';
import MemberContext from './component/MemberProvider';
function App() {
const [state, actions] = useContext(MemberContext);
return (
<>
{
state.user?
return logOut : return login
}
</>
)
}
앞구르기 하고 봐도 psedo인 code를 남기고 이만 실제 코드에 적용한 결과는 다음에 알아보도록 하겠다.