이미 눈치채셨겠지만
이 컨텍스트 기능은 앱 내의
여러 컴포넌트간의 데이터 공유에 매우 유용합니다
그러나 현재 여러분들이 사용하고 있는 방법으로는
여전히 꽤나 무거운 앱 컴포넌트가 된다고 볼 수 있습니다
왜냐하면 우리는 결국
컨텍스트를 통해 공유될 값의 설정을
이 컴포넌트 안에서 하고 있기 때문입니다
이 또한 구동에는 문제가 없겠지만
좀더 복잡한 앱이라면 하나의 앱 안에
여러 개의 컨텍스트가 있을 가능성도 있기에
이러한 경우는 피하는 것이 좋습니다
다른 상태값들을
각각의 다른 컨텍스트로 공유해야 하는 상황이 생길 수도 있습니다
그렇게 된다면 결국
컨텍스트를 사용할 모든 컴포넌트에 대한
접근 권한을 가지고 있는
앱 컴포넌트는 root(루트) 컴포넌트이므로
엄청난 양의 로직이 쌓이게 될 겁니다
그렇기에 이를 대체할 접근법이 있습니다
여러 리액트 프로젝트에서
이 패턴이 사용되는 것을 보게 될 텐데
이 모든 컨텍스트 관련 데이터 관리를
앱 컴포넌트가 아닌 별개의 컨텍스트 컴포넌트에 넣을 수 있도록 해 주는 것입니다
이제 이 패턴을 사용하는 법을
여기 shopping-cart-context 파일을 이용해 알아보겠습니다
컨텍스트의 생성이나 공유와는 별개로
컴포넌트 함수를 생성하고 또 공유할 수 있는데
이것을 저는 CartContextProvider라고 하겠습니다
이름은 항상 그렇듯 임의로 정하시면 됩니다만
해당 컴포넌트 함수를 잘 묘사하는
이름을 사용하는 것이 좋습니다
이 컴포넌트 함수의 경우
컨텍스트 데이터를 관리하고
그 데이터를 앱에 제공하는 등
장바구니 쪽 컨텍스트와 연관되어 있으니
이 컴포넌트 함수 이름은 이렇게 짓겠습니다
이것의 목적은 간단히 말해
앱 컴포넌트 내에 있던
모든 상태와 컨텍스트 값의
관리 코드를 가져오는 것입니다
useState를 이용한 상태 생성부터
상태에 추가된 이 모든 함수를 다 포함시켜서
컨텍스트 값을 만들어둔 여기까지를 선택해서
이 부분을 모두 앱 컴포넌트에서 잘라내
가볍게 만들어 주도록 하겠습니다
그리고 이것을
제가 상태를 관리하게 될
CartContextProvider 컴포넌트 함수에 넣어 주는 것입니다
이것이 제대로 구동되기 위해서는
import 명령으로 이 파일에 useState를 불러와야 합니다
그리고 이렇게 불러오고 나면
가짜 물품 또한 불러와야 합니다
여기 이렇게 한 층위 위의 초기 프로젝트에 있는
dummyproducts.js 파일로부터
가짜 물품을 불러와 줍니다
이렇게 되면 해당 컴포넌트 함수 내에서
상태 전체를 관리하는 것에 더해
컨텍스트 값 또한 여기에 만들어둘 수 있습니다
다만 아직은 완벽한 컴포넌트 함수라고 할 수 없는데
그 이유는
현재로선 렌더링이 가능한 그 무엇도 반환하지 않기 때문입니다
이 부분에 대한 작업이 필요합니다
반환하고자 하는 것은 CartContext.Provider 컴포넌트인데
여기 있는 값 속성은
이 컨텍스트 값으로 설정되어 있습니다
이 CartContext.Provider 컴포넌트는
특정 값을 묶어주는 역할을 해야만 하는데
우리가 커스텀으로 만들어둔 이 CartContextProvider가
묶이도록 해주면 됩니다
여기에서는 이 자식 속성을 받아서 구조 분해(destructure)하고
그리고 그것을 이쪽 아래에서
JSX 코드 반환에 사용해 줍니다
이 값으로 CartContext.Provider를 묶어주는데
그 어떤 JSX 코드나 다른 컴포넌트라도 묶어서
여기 있는 CartContextProvider가
묶일 수 있도록 해주시면 됩니다
이렇게 이 CartContextProvider 컴포넌트를
앱 컴포넌트에서 사용할 수 있게 되었습니다
이제 shopping-cart-context.jsx로부터
이 CartContextProvider 컴포넌트를 불러와서
이전의 컨텍스트 객체를 대신하게 합니다
이제 여기에서는 상태 관리를 하지 않게 되었으니
이 useState를 삭제해 줍니다
이제 만들어둔 커스텀 컴포넌트를 사용해
Header와 Shop을 이렇게 묶어 주면 됩니다
아직 감싸는 부분을 설정 중이지만
여기 있던 상태 관리용 로직은
이제 모두 삭제되었습니다
저장해 주시고 다시 로딩을 해보면
이전과 같이 제대로 구동되고 있습니다
여전히 장바구니가 여기 있고 편집도 할 수 있지만
이제는 컨텍스트를 통해 구동되고 있는 것입니다
그리고 이 컨텍스트와 상태 관리 코드 모두를
별개의 컴포넌트로 외부에서 가져오고 있기 때문에
동일한 앱 내에 여러 개의 컨텍스트와
여러 조각의 독립 데이터가 있더라도
여러 개의 컨텍스트 파일을 생성해 사용함으로
앱 컴포넌트는 가볍게 유지할 수 있을 것입니다
왜냐하면 여기 이 CartContextProvider 컴포넌트를 이용해
해당 컴포넌트들을 묶어두기만 하면 되기 때문입니다