리액트 context API 에 대해 알아보자
props drilling 비켜라
들어가며😃
상태관리를 어떻게 더 쉽게 하는지에 대해 알아보다 리액트 context 를 통해 props를 내려주고, useReducer 를 통해 상태 변경을 해주는 조합을 알게되었다. 이 과정을 차근히 이해하기 위해 이전 포스팅에서 useReducer 훅을 정리해보았고, 오늘은 context 에 대해 정리해보려한다.
Context API
리액트 context는 컴포넌트에 props를 사용하지 않고 전역으로 데이터를 공유할 수 있도록 해준다. (여기서 데이터란, 값이 될수도 있고, 함수 혹은 DOM이 될 수도 있다.)
이러한 특성으로 context 는 props drilling 을 막는데 도움을 준다. 아래 예시 코드를 통해 더 알아보자.
props 로 값을 전달해주는 경우
// 가장 상위 페이지 컴포넌트
export default function State() {
const value = { name: "길동", age: "52" };
return (
<div>
<div>state 페이지</div>
<First value={value} />
</div>
);
}
// props 받는 첫번째 컴포넌트 (props 사용 x)
export default function First({ value }) {
return (
<>
<div>First Component</div>
<Second value={value} />
</>
);
}
// props 받는 두번째 컴포넌트 (props 사용 x)
export default function Second({ value }) {
return (
<>
<div>Second Component</div>
<Third value={value} />
</>
);
}
// props 받는 세번째 컴포넌트 (props 사용 o)
export default function Third({ value }) {
return (
<>
<div>Third Component</div>이름 : {value.name}, 나이 : {value.age}입니다.
</>
);
}
위의 코드를 보면 가장 상위의 페이지 컴포넌트에서 선언한 value 값이 세번째 컴포넌트로 전달되기까지, 첫번째, 두번째 컴포넌트를 꼭 거쳐야한다. props를 쓰지도 않는데 말이다!😡
자, 그럼 아래에서 context 를 통해 데이터를 공유하는 방식을 알아보자.
context 로 값을 전달해주는 경우
import { createContext } from "react";
// 과정 1 : createContext 메서드를 사용해 context를 생성한다.
export const MyData = createContext();
export default function UseContext() {
return (
<div>
<div>UseContext 페이지</div>
{/* 과정 2 : 생성된 context를 가지고 context provider로 컴포넌트를 감싼다. */}
{/* 과정 3: value prop로 원하는 값을 입력한다. */}
<MyData.Provider value=>
<First />
</MyData.Provider>
</div>
);
}
export default function First() {
return (
<div>
<div>First Component</div>
<Second />
</div>
);
}
export default function Second() {
return (
<div>
<div>Second Component</div>
<Third />
</div>
);
}
import { MyData } from "../../pages/useContext";
export default function Third() {
// 과정 4 : useContext 훅을 통해 위에서 생성한 context를 전달받는다.
const value = useContext(MyData);
return (
<div>
<div>Third Component</div>
{/* 과정 5 : props 를 사용한다 */}
<div>이름 : {value.name}, 나이 : {value.age} 입니다.</div>
</div>
);
}
결과는 짠!😇
props drilling 없이도 데이터가 최상단 페이지 컴포넌트에서 세번째 컴포넌트로 껑충 잘 전달되었다.🐰🐰🐰
위의 코드를 요약해보자면,
createContext
메서드를 사용해 context를 생성한다.- 생성된 context를 가지고
context provider로
컴포넌트를 감싼다. value prop로
원하는 값을 입력한다.useContext
훅을 통해 위에서 생성한 context를 전달받는다.(버전 16.8부터 가능함)- props 를 사용한다.
위에서 props를 계속 전달해줬던 방식에 비해 매우 간결하고 편리하게 데이터를 불러올 수 있었다. 마냥 편하기만 해보이는 이 방식에도 단점이라 해야할까? 주의사항이 있다고 한다.
context API 단점
context 가 위의 예제처럼 늘 똑같은 값을 가질때에는 문제가 없겠지만, Provider에서 제공한 value가 달라진다면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링는 것이다…🤢
그렇기 때문에 useMemo(), React.memo 또는 context를 쪼개서 사용하는 등의 메모이제이션 조치를 취해야하는데 해당 방식에 대해서는 다음 포스팅에서 이어해보겠다!!
하나만 알면 되는게 없는 리액트다.. 사실 처음엔 상태관리를 어떻게하면 좋을까 부터 시작했고, 상태관리하면 대표적으로 redux, redux-toolkit 등이 나와서 이부분에 대해 공부해보려고 찾아본건데.. 거기까지 가기도 전에 공부해야할 개념들이 아주 산더미다.
그래도 좋아보이는 점은 다음 프로젝트를 들어가기 전에 능동적으로 준비하고 있다는 점,, 당연한거지만 칭찬해주고 싶다💯
다음엔 아마 reducer 와 context 를 결합하여 어떻게 효과적으로 상태관리를 할건지 + 리렌더링을 막는법 에 관해 포스팅할텐데 무리없이 이해하고 어딘가에 적용해볼 수 있기를 희망하며!! 오늘도 포스팅 끝!!😎