
++ 리액트를 더 잘 쓰기 위한 정리 시리즈
쇼핑 앱에서 장바구니 기능을 만들었다고 가정해보자.
Cart 컴포넌트와 Product 컴포넌트 모두 장바구니에 필요한 상태관리가 필요하다.
그러려면 App 컴포넌트에서 장바구니 아이템을 정의하고 props로 Shop 컴포넌트에게 넘겨주어 Product 컴포넌트가 받을 수 있게 해야한다.
하지만 Shop 컴포넌트는 장바구니 관련된 데이터가 필요없다..
이런 현상을 Props Drilling 이라고 한다. 하위 컴포넌트가 더 겹겹이 쌓여 있을수록 하나하나 값을 전달해주려면 불필요한 props들을 정의해줘야 한다.

만약 장바구니 데이터를 관리하는 하나의 저장소를 만들어 관리하고, 이 데이터가 필요한 컴포넌트가 가져다가 쓰는 구조를 만들면 Props Drilling 문제를 해결할 수 있다.

1) Context 저장소 만들기
createContext 안에 문자열, 객체 다양한 값들을 넣을 수 있다. 상태 관리가 필요한 데이터의 타입과 저장할 변수명을 정의해준다.
// Context 저장소를 정의
export const ShoppingCartContext = createContext({
items: [],
addItemToCart: () => {},
updateCartItemQuantity: () => {},
});
장바구니에 담을 아이템 리스트와 장바구니 추가 및 변경 함수들을 정의해주었다.
2) Context API를 사용할 컴포넌트들을 감싸주기
위에서 정의한 Context 객체가 제공하는 Provider는 Context 값을 구독하는 하위 컴포넌트들에게 업데이트 소식을 전해준다.
관리하려는 초기값이 value이고 이 값을 props로 하위 컴포넌트들에게 전달된다.
// -------------ShoppingCartProvider ------------- //
// state 상태관리가 필요한 shoppingCart 변수를 Context API에서 연결해 사용할 수 있도록 설정
const ContextValue = {
items: shoppingCart.items,
addItemToCart: handleAddItemToCart,
updateCartItemQuantity: handleUpdateCartItemQuantity,
};
<ShoppingCartContext.Provider value={ContextValue}>
{children}
</ShoppingCartContext.Provider>
// -----------------App------------------ //
function App() {
return (
<ShoppingCartProvider>
<Header />
<Shop />
</ShoppingCartProvider>
);
}
export default App;
3) Context 값 사용하기
useContext 훅을 import 해주고 Context 저장소를 가져와서 연결해준다. 저장소에 정의한 items나 여러 함수들을 사용하면 된다.
import { useContext } from "react";
import { ShoppingCartContext } from "../store/shopping-cart-context.jsx";
export default function Cart() {
const { items, updateCartItemQuantity } = useContext(ShoppingCartContext);
Context API를 사용해서 Props Drilling을 방지하고, 컴포넌트의 재사용성을 높일 수 있다. 또한 하나의 context에서 상태를 관리하고 사용하기 때문에 App 컴포넌트의 복잡성을 줄이고 관련 로직들이 분산되지 않아 관리하기 더 편할것이다.
하지만 리액트 공식문서를 보니 Context API가 항상 좋은 대안이라고 할 수는 없다.
context의 주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것입니다. context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때만 쓰세요.
https://ko.legacy.reactjs.org/docs/context.html
다양한 방법들을 알고 있으면 선택지가 넓어짐과 동시에 더 쉽고 간단하게 구현을 할 수 있겠다는 생각이 든다.