이번 하반기 Dev-Matching 프론트엔드 과제를 대비하기 위해 지난 상반기 문제인 고양이 사진첩 애플리케이션
문제를 풀어보고 해설과 함께 복기해봤다.
(자세한 구현사항 등의 내용을 저작권 보호를 위해 제외하였습니다. 직접 과제 응시를 통해 확인해주세요!)
처음 시도에서는 감도 안잡혀서 다른 블로그 풀이를 참고해서 작성했다.
나는 html이나 Pug 같은 템플릿 엔진을 사용해 문서를 직접 작성하다가 바로 리액트 개발을 시작했다.
그래서인지 순수 자바스크립트만으로 리액트처럼 컴포넌트 형태로 구현하는 것이 어색하면서도 새로웠다.
(이것이.. 바닐라 자바스크립트...?!)
주어진 3시간동안 열심히 작성해 필수사항 중 절반을 구현하는데 성공했다.
어떻게 첫 술에 배부를 수 있을까! 처음치고는 나쁘지 않은 시도였다.
이전에 작성했던 코드를 프로그래머스에 업로드된 해설과 비교해보며 어떤 점이 부족했고
, 어떻게 개선할 수 있는지
에 초점을 두고 복기했다.
과제 중에는 코드 짜는데 정신이 팔려 잊고 있었지만 문제 설명에는 구현시 유의사항
항목이 있었다.
(구현시 유의사항에 대한 내용은 저작권 보호를 위해 제외하였습니다. 직접 과제 응시를 통해 확인해주세요!)
저번 시도에서는 첫 번째 항목인 컴포넌트 형태로 추상화
부터 막막하다 보니 나머지는 신경조차 쓰지 못했다. ㅎㅎ..
짧게 반성하면서 어떤 점들을 염두에 두어야 하는지 짚어보았다.
지문의 가급적 컴포넌트 형태로 추상화하여
는 명령형 프로그래밍 방식보다는 선언적인 프로그래밍 방식으로 접근하라는 뜻이다.
선언적 프로그래밍은 어떻게
가 아니라 무엇을
달성할지에 집중한다.
그 것들을 어떻게
달성할지는 추상화되어있는 것을 사용하거나, 추상화시킨다.
상태를 변경하는 모든 지점들은 함수 내부에 추상화되어 있고, 사용자가 직접 상태를 변경하지 않기 때문에 훨씬 가독성이 높고 재사용이 쉬워진다는 장점이 있다.
(참고: 박스여우님의 명령형 프로그래밍 VS 선언형 프로그래밍)
이를 UI 개발에 적용한다면 다음과 같은 점들을 생각해볼 수 있을 것이다.
무엇을
에 집중한 작업 흐름 작성하기새로운 내용 같았지만 막상 적고 보니 이미 React에서 사용하고 있는 방식이었다.
역시 제대로 알고 사용하는 것이 중요하다는 것을 다시금 느꼈다!
다른 컴포넌트에 직접적으로 간섭하는 작업은 컴포넌트를 종속되게 만들어 재사용을 어렵게 한다.
그렇다면 특정 이벤트가 발생했을 때 다른 컴포넌트의 상태를 조작해야 한다면 어떻게 해야할까?
어디에서 이벤트를 처리할지 먼저 정하고 핸들러 함수를 매개변수로 받아 처리하는 방법이 있을 것이다.
이렇게 되면 이벤트 처리 로직에 구애받지 않고 해당 컴포넌트를 재사용할 수 있다.
이 역시 기존에 리액트에서 많이 사용한 방법이다. 바로 부모에서 자식에게 props로 전달하는 이벤트 콜백 함수다.
데이터를 API 서버에서 받아오는 로직은 사실 App 컴포넌트에게는 중요하지 않다. 어떻게
받아오느냐는 중요하지 않다. App 컴포넌트는 무엇을
받아올지, 그리고 그 데이터를 자식 컴포넌트에게 전달하는 것에만 신경쓰면 된다.
해당 코드는 별도의 유틸리티 함수로 분리하는 것이 가독성과 재사용 측면에서 훨씬 유리하다.
다른 사항들을 대부분 이미 사용하고 있지만 인지하지 못한 것들인데, 이벤트 위임은 완전 새로운 내용이었다.
아이디어는 간단했다.
발생한 이벤트는 상위 요소로 계속 전파된다.(이벤트 버블링) 따라서 이를 복수의 요소에 핸들러를 부착하지 말고 서, 하나의 부모 요소에게 부착해 이벤트 처리를 위임하자는 것이다.
이를 가능하게 하는 것은 Web API의 Element.closest()
메서드다.
해당 메서드를 사용하면 부모 요소에서 while 노가다 없이도 event.target.closest()을 통해 원래 이벤트를 처리하고자 했던 요소를 찾을 수 있다.
이벤트 위임을 사용하면 하위 요소 하나하나 이벤트를 걸지 않아도 될 뿐만 아니라, 다시 렌더링되지 않는 상위의 요소에서 이벤트를 처리함으로써 렌더링마다 다시 이벤트를 걸지 않아도 된다.