구직을 준비하면서 포트폴리오를 제출해야 될 때가 많았다.
노션으로 준비해서 제출했었는데 나도 나만의 포트폴리오 사이트를 갖고 싶다는 생각을 하고 있었다.
근데 맨날 우선순위가 뒤로 밀려서 ...
이러다 영원히 미루겠다 싶어서 엘리스에서 포트폴리오 만들기 스터디(?)를 꾸려서 완성하게 되었다.
3주 간 각자의 진행사항과 꿀팁 공유하는 식으로 점검과 추진을 할 수 있도록 스터디를 하였고, 완성까지는 아니지만 대부분이 틀은 완성하였다.
잘 따라와주셔서 감사했슴다 🥹
마지막 주차는 각자의 사이트를 보여주고, 서로 피드백해주는 시간도 갖으면서 완성도를 높일 수 있었다.
진심 어린 피드백이라 도움이 많이 되었던 것 같다.
React를 이용하여 구현하였다. 가장 신경썼던 부분이 내가 데이터를 추가해도 지금의 틀을 유지할 수 있도록 하는 것이었다. 즉, 재사용이 자유롭게 되도록 만들었다.
전체 페이지부터 세세한 컴포넌트까지 데이터의 규격만 벗어나지 않으면 들어가도록 구현하였다.
이제 나는 추가하고 싶은 카테고리부터 경험까지 데이터만 넣으면 뙇! 나온다.
(조금 많이 뿌듯했다.)
다만, 아쉬운 점은 프로젝트 카테고리와 그 카테고리가 닮았지만 다른 컴포넌트라는 것이다. 프로젝트 설명 부분은 포트폴리오를 보시는 분들이 똑같은 형식으로 보시면 이해하시기가 편할 것 같아서 좀더 구체적인 컴포넌트로 구성하게 되었다. 근데 막상 만들고 나니깐 어차피 비슷하게 생겼는데 모든 카테고리를 하나의 컴포넌트로 하는 것이 추후에 확장성을 위해선 더 좋지 않았을까? 라는 아쉬움이 남는다.
또, 아쉬운 점은 netlify로 배포하여서 도메인이 마음에 들지 않는다는 것이다... 도메인을 살까? 싶기도 한데 본격적으로 채용 시즌이 시작되면 사야지 하고 미루고 있다. 서버리스 서비스 중에 도메인이 이쁜 것이 많다는 것도 뒤늦게 알게 돼가지고... 차차 수정해야지 마음 먹고 있다. 😔
그래도 호로록 내가 구상하던 것은 다 만들었고, 주위에 보여줬을 때 리액션들이 풍부해서 좋았다. ㅎㅎ
내가 고려했던 부분도 잘 반영된 것 같고, 이제 어딘가에 보낼 때 매번 보낼까 말까 고민하지는 않아도 되는 결과물이 아닐까 하였다.
엘리스를 떠나 싸피를 시작하게 되면서 적응하느라 혼났다.
아무래도 4개월 내내 수업 듣다가 또 수업을 들으려니깐 많이 지쳤다.
그리고 주위에 취뽀 소식이 들리면서 괜히 상반기에 하반기를 노리겠어!!! 라고 했던 게 후회도 되면서 이래저래 갈대마냥 시간에 몸을 맡겼다.
목표를 하나 정하면 그걸 해내야 직성이 풀리는 고집이 있어서 하반기에는 꼭 취업하고 말겠다는 일념으로 몇몇 채용에 지원하였다.
그러면서 잠시 잊혀졌던 포트폴리오가 생각나면서 내가 추가하고 싶었던 기능이 생각났다.
아무래도 난 신입이니깐 이런 저런 증명서를 넣고 싶었다. 여러 포트폴리오들을 봤는데 증명서를 넣진 않았지만, 난 내가 해왔던 경험에 자신이 있고(!!) 넣어보면 좋지 않을까? 라고 생각했었다. 그리고 이제 넣을 차례다 싶어서 주말에 feature-pdf-viewer이라는 브랜치를 팠다.
여러 채용을 흘깃 거려본 덕에 증명서는 대부분 pdf를 제출한다는 것을 알게 되었다. 단순히 사진을 넣어도 되지만 나에게는 pdf 자료가 더 많고, 굳이굳이 또 사진을 준비하기에는 쓸데 없다는 생각이 들었다.
그래서 pdf를 보여주는 팝업을 생각했고, 아래 라이브러리를 찾았다.
react-pdf
아주 쉽다. 난 한 페이지를 보여줄 것이고, 파일만 준비하면 된다.
다만, 주의해야하는 것이 file 속성이 꼭 String 타입이어야 해서, props로 받아온 것이 String인지 체크해줘야한다. 이때 props 타입 확인 부분을 추가해주면 된다.
Modal.propTypes = {
filePath: PropTypes.string,
};
버튼을 누르면 모달을 띄우고 그 안에서 pdf를 보여주는 것으로 구성하였다.
버튼
먼저 모달을 열 버튼을 준비한다.
나는 데이터를 객체로 두고 file이라는 데이터가 있다면 팝업 버튼을 생성하엿다.
그리고 그 file을 모달에다가 전달해야 모달 내의 react-pdf에 file을 전달할 수 있다.
모달
생각해야 할 점이 이것이 공통 컴포넌트로 modal이 열리는 부분이 그 페이지 전체가 되어야 한다.
컴포넌트 생성 부분이 아니라 이것을 감싸는 부분에서 모달을 열어야 해서 filePath라는 상태를 두고 버튼이 눌린다면 해당 상태에 해당 데이터의 file 경로로 바꿔주고 그것을 모달에게 전달하는 방식을 택하게 되었다.
const [modal, setModal] = useState(false);
const [filePath, setFilePath] = useState("");
const handleClick = (file) => {
setModal(!modal);
setFilePath(file !== undefined ? file : "");
console.log(modal, file);
};
...
{modal ? <Modal handleClick={handleClick} filePath={filePath} /> : null}
modal을 isModalOpened로 리팩토링 해야겠다.
그럼 위와 같이 pdf를 보여주는 모달! 완성..!
모달은 이로써 세번째 구현이다. 매번 놓쳤던 부분이 있는데 사용자 경험에 의해 우리는 바깥에 검은 부분을 터치하면 모달이 꺼진다고 인식한다. 이번에는 이 부분도 구현해야겠다고 생각하고 여러 자료를 찾아봤다. 해당 기능은 outside click이라고 한다.
그 중 이 분의 포스트가 가장 도움이 많이 됐다.
참고 포스트
위를 참고하여 알게 된 것이 많았다.
이벤트가 발생하면 최상위 요소까지 이벤트가 발생하는 것
이벤트가 제일 깊은 곳에 있는 요소에서 시작해 부모 요소를 거슬러 올라가면 발생하는 현상
특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미함.
이는 브라우저가 이벤트를 감지하는 방식이다. 하위 에서 상위요소로의 이벤트 전파 방식
이를 위해 event 객체의 두 가지 target을 알아야 한다.
event.target
: 실제 이벤트가 시작된 타깃 요소
event.currentTarget
: 현재 요소, 현재 실행중인 핸들러가 할당된 요소
Ref
특정 노드나 컴포넌트에 레퍼런스 값을 만들어주는 것. 때문에 이를 통해 노드나 리액트 요소에 접근하여 값을 얻어낼 수 있습니다.
useRef
로 구성 가능하다
아이디어
많이 참고하였다.
- 문서 전체에 이벤트 리스너
- outside 클릭의 기준이 되는 HTML 요소를 잡아준다.
- 클릭 이벤트 mousedown 발생시, event.target이 ref에 저장된 요소를 포함하는지 확인한다.
- 포함되지 않는다면 outside 클릭이다.
위 방법을 내 코드에 적용시켰다.
useEffect(() => {
document.addEventListener("mousedown", handleModalOutside);
return () => {
document.removeEventListener("mousedown", handleModalOutside);
};
}, []);
const modalRef = useRef();
...
<ModalBox ref={modalRef}>
const handleModalOutside = (e) => {
if (!modalRef.current.contains(e.target)) {
handleClick();
}
};
포함이 되지 않으니 outside click이 발생한 것으로 보고 모달의 상태가 변하도록 handleClick을 실행한다.
ref의 개념이 명확하지 않았는데 특정 요소의 정보? 상태를 참조할 수 있어지는 구나를 확연히 느낄 수 있었다.
언제나 어려운 프론트의 세계....
하지만 그래서 흥미로운 것 같다. 🥹
아무튼 완성하여 내가 바라던 기능을 완성할 수 있었다. 앞으로도 자잘하더라도 기능을 업데이트할 것이다.
다음 기능을 기대해주세요 ㅎ!