이제 결제 컴포넌트로 돌아와서
커스텀 useHttp 훅을 사용해 보겠습니다
여기서는 조금 다른 방식으로 사용해야 하는데
여기에서 요청을 바로 보내는 대신에
이 양식이 제출된 이후에 보내야 합니다
다행히 이 커스텀 훅을 만들 때에
정확히 이 부분을 인지하고 만들었습니다
결제 컴포넌트에서 useHttp를 사용하겠습니다
즉 커스텀 훅을 가져와서 사용하겠습니다
그리고 URL 주소도 하나 설정하겠습니다
이 주소로 모든 요청을 보낼 것입니다
주소는 localhost:3000/orders입니다
다음으로는 구성 객체를 이 커스텀 훅으로
보내야 합니다
이전과 동일하게 이 객체는 컴포넌트 함수의 밖에서 생성해야
무한 루프에 빠지지 않을 수 있습니다
이 구성 객체는 메소드 속성이 필요한데
이 속성은 POST로 설정하고
헤더 속성도 필요한데
이 속성은 Content-Type과 application/json으로 설정하겠습니다
여기에 JSON 데이터를 보낼 예정이기 때문입니다
물론 아직 바디 내용을 설정할 수는 없습니다
이 데이터는 양식이 작성된 후에만
가져올 수 있기 때문입니다
그러므로 이 훅의 내용을 조금 수정해서
몇 분 뒤에도 사용 가능하도록 하겠습니다
지금으로서는 이 구성만 설정하겠습니다
이제 요청 구성이 커스텀 훅에
전달되고 있습니다
이 요청 객체의 메소드가 POST로 설정되어 있고
커스텀 훅 안에 있기 때문에
바로 요청을 보내지는 않을 것입니다
그 이유는 이 과정을 실행하는 조건이
구성 메소드가 GET으로 설정되었을 때인데
그렇지 않기 때문입니다
그러므로 초기에는 아무 요청도 보내지 않고
커스텀 훅에서 가져온 객체에서
데이터를 추출할 수 있습니다
여기에서 데이서와 상태를 받는데
상태는 즉 isLoading과 에러 상태입니다
이 컴포넌트에서 아주 중요한 부분은
이 sendRequest 함수입니다
이 컴포넌트에서는 요청을 수동으로
직접 보내야 하기 때문입니다
그러므로 이제는 handleSubmit에 있고
여기에서 sendRequest를 요청하게 되는데
이것은 커스텀 훅에서 요청을 보내기 위해 가져온 것입니다
이제 데이터를 sendRequest로 전달해서
데이터가 전달되도록 해야 합니다
그러므로 다시 커스텀 훅으로 돌아가서
좀더 유연하게 수정해 보겠습니다
여기에서 sendRequest도 데이터를 받아야 하는데
만약 데이터가 필요하면 이 데이터를 보내기도 해야 합니다
그리고 이 구성과 합쳐져서
여기에 새로운 객체를 만들어야 합니다
이 객체에 기존 구성 옵션을 펼치겠습니다
그리고 또 이 객체에서 현재 받고 있는 데이터의 바디를
설정해 주겠습니다
수정 작업을 모두 끝낸 뒤에는
이제 sendRequest는 데이터가 어떤 시점에 보내지도록
사용될 수 있는데, 즉
우리가 요청을 보낼 준비가 될 때입니다
반대로 이 다른 요청 구성은 미리 만들어져 있습니다
이제 sendRequest로 보낸 데이터가
바디의 데이터이기도 하므로
또 이 요청에 JSON 데이터를
보내고 있으므로, 여기서 필요한 작업은
JSON 데이터를 보내서 요청을 보내게 하는 것입니다
즉 이 값 전체를 가져오게 되는데
이 JSON 값을 sendRequest의 입력값으로 받는 것입니다
이제 이 부분이 코드를 대체하고
컴포넌트를 좀더 간결하게 만들어 줍니다
이제 다양한 상태를 제어해 보겠습니다
예를 들면 isLoading 상태는 로딩 중에 사용되는데
즉 데이터를 보내고 있는 도중입니다
그러므로 여기에 별칭을 더해서
코드를 더 정리할 수 있습니다
이 작업을 위해
예를 들어 이 버튼을 보이고 싶지 않을 수 있습니다
버튼 대신에 사용자게에 지금 요청을 처리 중이라는
메시지를 보여주는 것입니다
그러므로 이 버튼을 조건부로 반환하는 것인데
이 작업을 위해 새로운 변수를 더하겠습니다
이름은 actions로 하겠습니다
여기에서 표준 내용이 바로 이 두 버튼이 될 수 있습니다
그래서 이 버튼을 잘라내서
프래그먼트로 감싸도록 하겠습니다
그리고 isSending이 True인지 보겠습니다
만약 그렇다면 actions는 span으로서
'주문 데이터 보내는 중...'이라고 할 수 있습니다
이 actions 변수가 이 모달 액션 문단의
반환값이 되는 것입니다
이대로 저장한 후
장바구니에 항목을 담아서
결제창으로 넘어가 보겠습니다
여기에 데이터를 입력하고
네트워크 툴을 열어서 스로틀링을 걸겠습니다
이렇게 하면 요청이 좀 더 오래 걸립니다
이제 주문서 전송을 누르면
아까 만든 '주문 데이터 보내는 중...'이 보입니다
그리고 주문 전송이 완료된 후
더이상 보내는 상태가 아닐 때에는 이 버튼이 또 보입니다
로딩 상태나 전송 상태를 제어하는 것 외에
이제는 에러 상태 작업을 해 보겠습니다ㅣ
예를 들어서 어떤 문제가 생겼을 때
이 버튼 위로 에러 메시지를 띄우는 것입니다
여기에서 에러가 True인지 확인하고
만약 그렇다면 아까 만든 에러 컴포넌트를 반환하되
제목은 '주문 전송 실패'로 하겠습니다
그리고 메시지는 에러 상태와 동일하게 설정하겠습니다
이렇게 하면 됩니다
이제 문제가 생기면 이 에러 메시지를 보여줍니다
그리고 확인해 보기 위해
주소를 다시 다르게 설정하겠습니다
이대로 저장한 후에
여기에 데이터를 입력하면
테스트를 위한 가짜 데이터입니다
스로틀링을 걸고 주문을 전송하면
이 로딩 상태가 뜨고 곧 에러가 나옵니다
즉 이 상태도 잘 작동합니다
이제는
다시 정상적인 주소로 돌려놓고
마지막으로 할 작업은
모든 작업이 잘 끝났을 때에도 메시지를 보여주는 것입니다
다시 결제 컴포넌트로 돌아와서
여기쯤의 위치에서 확인할 내용은
데이터를 가져오면, 즉 에러가 없이
적합한 응답을 받게 되면
데이터를 받고 응답이 없다면
이 경우에는 모달을 하나 반환하되
다른 모달을 반환하겠습니다
이 모달이 열리는 시점은
progress가 checkout일 때입니다
그리고 onClose에서는 handleClose를 실행시키겠습니다
이 부분은 이전과 같습니다
그런데 이 모달에서는
반환하는 제목을 '성공'으로 하겠습니다
그 아래에는, 문단을 하나 더해서
'주문이 정상적으로 이루어졌습니다'라고 쓰겠습니다
그리고 다른 내용도 좀더 쓰겠습니다
'주문에 대한 상세 내용을'
'몇 분 안에 이메일로 보내드리겠습니다'
그리고 그 아래에는
문단을 추가해서 className을 modal-actions로 하겠습니다
여기에서는 커스텀 버튼을 사용한 버튼을 만들어서
'확인(Okay)'을 띄우겠습니다
그리고 이 버튼을 클릭하면 모달이 닫히게 됩니다
즉 주문이 정상적으로 이루어졌다면
이 간단한 성공 메시지를 띄우는 것입니다
이 작업이 끝났으니 다시 돌아가서
장바구니에 항목을 담고
결제창으로 넘어가서
다시 데이터를 입력하겠습니다
가짜 데이터이므로, 아무 내용이나 해도 됩니다
그리고 전송하면
조금 있으면 아까 만든 성공 모달이 뜨고 닫히기도 합니다
물론 여기에서 한 번 더
주문을 할 수도 있으므로 이 경우에는
주문이 끝난 경우 장바구니를 비워야 합니다
그러므로 여기에 함수를 하나 더하겠습니다
위치는 handleClose 아래로 하고
함수 이름은 handleFinish로 하겠습니다
여기에서는 hideCheckout을 쓰지만
그와 동시에 장바구니를 비우기까지 하겠습니다
이 마지막 단계를 위해서는 다시
장바구니 컨텍스트로 돌아가서 함수를 더해야 합니다
이 함수가 이 작업을 할 것입니다
그리고 액션을 하나 더해서
리듀서(reducer)에서 장바구니를 비우도록 하겠습니다
이것부터 작업을 하겠습니다
장바구니 리듀서에서
즉 장바구니 리듀서 함수에서는
액션 유형이 CLEAR_CART인지 확인하겠습니다
만약 그렇다면
이전 상태를 복사하는 새로운 상태를 반환하되
항목을 빈 배열로 설정하도록 하겠습니다
이 작업을 통해 장바구니를 비울 수 있습니다
이제 컨텍스트 안에 새 함수를 더하겠습니다
이름은 clearCart로 하고 이 임시 초기값에 더해서
나중에 자동 완성이 더 용이하게 하겠습니다
그리고 이것을 아래에서 한 번 더 더하는데
위치는 물론 CartContextProvider입니다
그리고 claerCart 함수는 새로운 장바구니 액션을 실행하되
유형을 CLEAR_CART로 설정하겠습니다
이것이 이 액션인데
이 장바구니 리듀서에 더한 로직이 이 액션에 대한 것입니다
이제 clearCart를 더하겠습니다
이렇게 컨텍스트 객체에 더하겠습니다
이제 다시 계산 컴포넌트로 돌아와서
handleFinish에서 장바구니 컨텍스트를 써서
clearCart를 불러오겠습니다
이렇게 하면 결제 모달을 닫을 뿐만아니라
장바구니도 비울 수 있게 됩니다
이데 handleFinish가 실행되는 시점은
이 성공 모달의 확인 버튼을 누르는 떄입니다
그리고 그 외에 다른 방식으로 창을 닫아도 마찬가지입니다
이제 드디어 다시 돌아가서
결제창으로 넘어가 본 후에
빠르게 가짜 데이터를 입력하고
주문을 전송하고 확인을 누르면
이제 장바구니가 비워졌습니다
이제 스로틀링을 꺼도 됩니다
이제 거의 완성된 모습을 갖춘 앱이 되었습니다
거의 완성되었다고 하는 이유는 한 가지 작업이 남아있기 때문입니다
지금은 정상적으로 결제가 완료되고
새로운 항목을 장바구니에 담고
한 번 더 결제창으로 넘어가 보면 문제가 생깁니다
빠르게 주문을 한 번 보내겠습니다
그리고 다시 항목을 장바구니에 담고
이 항목도 구매하려고 해 보면
다시 성공 화면이 뜨는 것을 볼 수 있습니다
이 화면이 뜨는 이유는 현재 시점에서
이 결제 컴포넌트에는
커스텀 훅에서 가져오는
데이터 상태가 있고
이 상태가 이전 주문에서 받아온
성공 응답에 설정되어 있기 때문입니다
즉 리셋이 되지 않은 것입니다
이 문제의 해결방식으로는
useHttp에 새로운 함수를 더해서
clearData라고 이름을 짓겠습니다
여기에서는 setData를 호출해서
커스텀 훅의 입력값으로 받은 초기 값으로 재설정하겠습니다
이제 clearData 함수를 커스텀 훅에서 노출하고
다시 결제 컴포넌트로 돌아가서
clearData 함수를 사용하겠습니다
사용 시점은 성공 모델을 닫을 때마다입니다
즉 handleFinish에서 clearData를 호출하고
이렇게 하면 커스텀 훅이 만든 데이터를 삭제하게 됩니다
이제 새로고침을 하고 항목을 장바구니에 담고
빠르게 주문을 전송해 보겠습니다
주문을 전송하고 다시 장바구니에 항목을 담겠습니다
다시 결제창으로 넘어가서
결제를 한 번 더 해 보겠습니다
이제는 정상적으로 작동하는 것을 볼 수 있습니다
이제 드디어 이 앱 개발 작업이 끝났습니다