이번 강의에서는 이 장바구니 버튼이
장바구니 정보를 보여주는 모달을 열도록 하겠습니다
이것을 위해서는 일단 모달 작업을 해야 합니다
모달이란 화면에 새로운 창으로 뜨는 컴포넌트입니다
이 모달을 독립형, 재사용 가능한 UI 컴포넌트로 만들어
이 모달을 앱의 다른 위치에서도
사용할 수 있도록 하겠습니다
나중에 보시겠지만 실제로 다른 위치에서 사용하기도 합니다
일단 Modal.jsx을 생성하고
여기에 모달 컴포넌트 함수를 내보내겠습니다
이 모달 컴포넌트 함수에서는
리액트에 포함된 대화상자(dialog) 요소를 반환하겠습니다
이 요소는 모달처럼 창을 새로 띄울 때 유용합니다
해당 작업의 복잡한 부분을 대부분 해결해 주기 때문입니다
이 요소를 내보낼 때에는
포탈(portal) 기능의 도움을 받겠습니다
이제 이 모달 컴포넌트를
컴포넌트 트리의 어느 위치에서나 사용이 가능합니다
그러나 대화상자는 이 컴포넌트가 DOM의
특정 영역에 보일 때에 주입하겠습니다
이것은 개발자가 제어하는 내용입니다
여기에 div를 하나 주입하겠습니다
modal이라는 id의 div입니다
모달 컴포넌트로 대화상자를 생성하고 열 때
그 대화상자 요소를 여기에 주입하겠습니다
물론 그것이 포탈 기능의 내용입니다
이전 강의에서 이미 배우신 내용입니다
포탈을 만들어서 리액트 DOM에서 가져온
createPortal 함수의 도움을 받으면
반환하는 값은 대화상자 요소가 아니라
리액트 포탈에 대한 호출입니다
즉 다른 곳으로 보낼 JSX 컨텐츠
이 컴포넌트로 렌더링되어야 하는 컨텐츠가
createPortal의 첫 인자로서 전달됩니다
두 번째 인자에 해당하는 코드는
DOM의 요소를 지정합니다
여기에서는 document.getElementByID를 사용해
모달의 ID로 요소를 지정하겠습니다
즉 이 div입니다
이렇게 포탈을 만들었습니다
이 모달 컴포넌트에 대한 의의는
원하는 컨텐츠를 감싸서 해당 컨텐츠를
대화상자에 넣기 위함입니다
그러므로 자식 속성을 받아서 구조 분해 할당하고
이 대화상자 요소 사이로 전달하겠습니다
추가로 해야 할 작업은
이 모달 컴포넌트를 제어하기 위해
open이라는 속성의 도움을 받을 것인데
이 속성은 커스텀 모달 컴포넌트에서 설정하여
대화상자가 열렸는지 여부를 제어합니다.
이 빌트인된 대화상자 요소는
open가 속성으로 설정될 수 있고
open은 prop으로써도 전달될 수 있어서
open을 open으로 전달하는 게 가능합니다
그러나 이렇게 하면 몇 기능을 놓치게 되고
가장 중요하게는
이 대화상자 요소를 직접 구현하면
즉 open 속성(prop) 설정을 하지 않으면
이 요소는 백드롭(backdrop)을 보여줍니다
백드롭이란 새로 뜨는 창의 뒷쪽 면이고
이 면은 다른 내용을 모두 가리거나
내용 위를 덮음으로써
대화상자가 열려있는 동안
상호작용하지 못하게 합니다
그러므로 open 속성(prop) 설정을 통해
열지 않으려고 합니다
이 대신에
대화상자를 직접 구현하겠습니다
한 가지 방법은
이전 강의에서 배우셨듯이
참조 전달를 사용해
함수를 커스텀 컴포넌트에서 다른 컴포넌트로
노출하도록 할 수 있습니다
그러면 다른 컴포넌트가 이 함수를 호출해서
대화상자를 열거나 닫을 수 있습니다
이 방법도 가능은 하지만
여기서는 다른 방식으로 작업하겠습니다
useEffect를 사용해서
조금 더 실습에 사용해 보기도 하고
open 속성값이 변할 때마다
네이티브(native)한 대화상자 요소와 상호작용하도록 하겠습니다
그래서 open을 의존성(dependency)으로
해당 배열에 전달하겠습니다
그러면 이 effect 함수가 open이 변할 때마다
재실행됩니다
그리고 effect 함수 내에서
open이 true인지 확인하겠습니다
만약 true라면
이 대화 상자를 직접 구현해서 열겠습니다
이 작업을 위해 대화상자 요소에 접근이 필요합니다
이미 배우셨듯이
이 작업은 참조(ref)의 도움을 받아서 가능합니다
리액트에 포함된 참조 훅(hook)을
리액트에서 불러오고 참조를 호출한 뒤에
이 대화상자 참조를
빌트인된 대화상자 요소와 연결하겠습니다
이 과정은 빌트인된 참소 속성의 도움을 받습니다
이제 이 effect 함수 안에
즉 이 if 블록 안에
if open이 true일 때만
이 대화상자 참조를 사용해서 showModal을 호출합니다
이것도 또 다른 내장 메소드로서
대화상자 객체를 띄우기 위해 실행됩니다
즉 직접 구현하여 여는 것입니다
닫는 기능은 조금 있다가 작업하겠습니다
모달 컴포넌트와 대화상자 기능에 대한
이 작업을 마치기 위해서
일단 className 속성을 더함으로써
이 대화상자에 모달 클래스를 추가하겠습니다
사실 이것을 더 동적으로 만드는 것이 좋겠습니다
이 모달 컴포넌트가 컴포넌트 바깥에서부터
형식을 정할 수 있도록 하겠습니다
그렇게 되면 다른 컴포넌트가 className 속성을
이 모달 컴포넌트에 설정할 수 있습니다
그러면 이 값은 결국
적용되는 모달 클래스와 병합됩니다
이 과정을 위해서는
className을 동적인 값으로 설정하면 됩니다
이 값은 결국 템플릿 리터럴 문자열로
저는 여기에 하드 코딩(고정된 값의 코딩)한 모달 클래스를 넣고
추가로 받게 될 수도 있는
className 또한 주입합니다
이론적으로는 이렇게 하면
className이 설정되지 않았다면 여기에 undefined 값을
className으로 추가하게 됩니다
그러므로 여기에 초기값으로
빈 문자열을 하나 넣어서
만약 className이 외부로부터 설정되지 않았다면
따로 여기에 텍스트를 넣지 않겠습니다
이번 시간 모달 컴포넌트 작업은 여기까지 하겠습니다
다음 시간에는
이 컴포넌트를 가지고 장바구니 내용 작업을 하겠습니다