지금 상황에서
이 컨텍스트 값은 고정적입니다
항상 빈 배열로 설정되어 있기 때문입니다
지금의 목표는 이것을 상태와 연결시키는 것인데
즉 이 쪽에 상태로 관리되고 있는
items 배열로 연결시키는 것입니다
이렇게 하는 방법은 다행히도 간단합니다
편의를 위해
초기 프로젝트에서부터 이곳의 상태를
상태에 주어지는 값과 동일한 모양의
객체로 만들어 두었습니다
그렇지만 우리는 그 상태를 변경해
이곳은 빈 배열이 유지하도록 하고
상태 업데이트는 그에 맞는 함수를 적용할 수도 있습니다
일단 저는 items 배열을 해당 객체 모양으로 두도록 하겠습니다
여기 상태에 있는 items 배열은
값으로 사용하는 것이 좋습니다
그렇게 하면 동적으로 사용이 가능하기 때문입니다
그렇다면 우리는
이쪽으로 내려가서 값을 설정하는데
우리의 shoppingCart 상태와 동일하게 해 주는데
이 것은 그 상태가 방금 언급한 것과
같은 구조를 갖고 있기 때문입니다
이제 저장을 하고 새로고침을 해서
장바구니에 물건을 추가하기 시작하면
해당 물품들이 장바구니에 이렇게 출력되는 것을 보실 수 있습니다
이제
우리는 컨텍스트를 상태에 연결을 마쳤는데
상태가 이제 단순히 제공되는 값이 되었기 때문입니다
즉 컨텍스트 기능을 이용해 wrap 컴포넌트와 자식 컴포넌트에게
제공되는 값이 되었기 때문입니다
컨텍스트를 상태에 링크시키는 것은 이렇게 쉽습니다만
이것으로 끝은 아닙니다
왜냐하면 제가 만약 상태 객체 전체를
이렇게 값으로 설정한다면
물론 읽는 것이 가능하기에
예를 들자면 여기 Cart 컴포넌트에
그 컨텍스트를 사용할 수 있을 것입니다
다만 상태를 수정하려면
아직은 컨텍스트를 통해 작동하지 못할 것입니다
대신, 컴포넌트에게 속성을 전달하는 방식으로
상태를 수정해야 한다는 뜻입니다
이상적인 경우에는
값을 읽는 데에 그치는 것이 아니라
해당 값을 업데이트하는 것 또한 가능하도록
모든 것에 컨텍스트를 사용할 수도 있습니다
그렇다면 값을 업데이트 하고자 할 때
속성을 전달할 필요가 없어지는 것입니다
이 또한 다행스럽게도 무척 간단합니다
이 작업을 위해 저는 다시 수동으로 값을 생성하는 것으로 돌아와
보다 읽기 쉬운 코드를 만들어주기 위해
다른 층위에 생성해 보도록 하겠습니다
여기 제 컨텍스트 값이 있는데
지금은 비어있는 객체일 뿐입니다
이 안에 items 배열을 넣고 싶으니
shoppingCart.items 배열을 넣어주면
이것이 상태 items 배열 이되는 것입니다
그렇지만 이것은 제가 공유하고자 하는 전체 값이 아닙니다
대신 저는 addItemToCart 함수를 함께 공유하고 싶습니다
addItemToCart 라는 속성인데
이것은 장바구니에 새로운 물건을 담아주는
기능을 가진 것이여야 할 것입니다
다행히 이미 이것을 가지고 있습니다
바로 여기 보이는 handleAddItemToCart입니다
이곳에 추가한 addItemToCart 속성을 위한 값으로
이 함수를 사용할 수 있는 것입니다
이렇게 우리는 컨텍스트를 통해
이 함수 자체를 노출시키는 것이기도 합니다
이 컨텍스트를 읽을 수 있는 컴포넌트라면
다시 말해 여기 Provider 컴포넌트로 묶여있거나
묶인 컴포넌트의 자식 컴포넌트일 경우
결과적으로 봤을 때는 모두
저의 컨텍스트 값에 있는 addItemToCart 속성을 통해
이 handleAddItemToCart 함수의 기능을 불러올 수 있는 것입니다
그러므로 우리는 이제 이 ctxValue 라는 상수를 제공할 수 있게 되었습니다
이 객체는 우리 컨텍스트의 값인데
그렇기 때문에 예를 들자면
여기 Product 컴포넌트에서
장바구니에 물건을 추가할 수 있도록 만들어주고 싶다면
해당 지점으로 가서
더 이상은 필요가 없어진
onAddToCart 속성을 삭제합니다
그리고 이쪽에는 우리 컨텍스트를 불러오려 하는데
한 층위 위로 올라와서, store 폴더의
shopping-cart-context.jsx 파일의
CartContext를 가져올 수 있도록 하고
이 컴포넌트 함수를 컨텍스트와 연결시켜 주는 데에는
리액트의 useContext 라는 훅을 사용하면 되는데
이 또한 보시는 것처럼 가져올 수 있도록 설정해 줍니다
Product 컴포넌트 함수에서는
cartCtx로 카트 컨텍스트를 가져오는데
이 것은 useContext를 이용하면 됩니다
불러온 cartContext의 값을
useContext의 값으로 전달하는 것입니다
여기에서는 다시 구조 분해(destructure)를 사용하는데
보시면 자동완성 기능이
addItemToCart 함수를 추천해서 보여주지 않습니다
여기 컨텍스트 값에 그냥 추가해 넣는데
이것은 제가 컨텍스트의 초기값이 아닌
여기에 넣었기 때문입니다
그러므로 이 함수명을 가져다가
여기 컨텍스트 객체로 와서
비어있는 가짜 함수를 이 곳에 추가하겠습니다
실질적으로 사용되지는 않겠지만
자동완성 기능에 도움을 주는 용도입니다
이렇게 비어있는 함수를 여기 만들어 주는 것으로
보다 나아진 자동완성 기능을
기대할 수 있습니다
다시 아까처럼 이 Product 컴포넌트를
구조 분해하려고 해보면
보시다시피 이렇게
addItemToCart 추천이 보여집니다
이번에는 이 함수를 이쪽으로 불러와서
저의 ID를 전달하고자 합니다
아까 그 속성들은 삭제를 해두었고
이제 이것을 모두 저장하고 새로고침을 해 보면
오류가 없고
장바구니에 물건을 추가해서 확인할 수 있습니다
여전히 모두 잘 작동하지만
달라진 것은 이제는 컨텍스트의 도움으로 작동을 하고 있다는 것입니다
이제 컨텍스트의 사용은
읽히는 값을 제공하는 것뿐 아니라
값이나 함수를 불러와서
여기 shoppingCart와 같은
상태를 변경해 줄 수 있습니다
이 상태는 해당 컨텍스트에 값으로 사용되기에
우리 컨텍스트와 연결되어 있는 것입니다
그리고 이것이 바로
프로퍼티 내리꽂기를 사용하지 않고 컨텍스트를 사용해
값과 상태 업데이트용 기능을 가진 함수를
앱 안의 여러 컴포넌트와 공유하는 방법입니다
이제 이 방법으로
헤더(header)를 비롯한 다른 컴포넌트에 데이터를 전달하던
장바구니와 관련된 나머지 속성들을 없애 보겠습니다