triple-frontend icon indicating copy to clipboard operation
triple-frontend copied to clipboard

클릭 기능을 확장할 때 JSX 패턴을 사용하면 어떨까요?

Open giwan-dev opened this issue 3 years ago • 2 comments

실무에서 바로 쓰는 Frontend Clean Code / Slash 21 영상을 보고 영감을 받아 의견을 모아보려고 합니다.

문제점

클릭 핸들러에 기능을 확장할 때 명령형으로 작성하고 있기 때문에 일명 "handleXXXClick" 함수가 엄청나게 길어집니다. stopPropagation, 이벤트 로깅 등의 코드가 하나의 함수 안에 들어가게 됩니다. 나중에 기능을 수정할 때 구현을 계속 추가하기 때문에 점점 수정하기 어렵고 이해하기 힘든 코드가 됩니다.

<PromotionButton onClick={async (e) => {
  /* 하나의 함수에서 세 가지 기능을 수행 */
  e.stopPropagation()

  trackEvent({ /* ... */ })

  await submit()
}} />

해결책

JSX의 선언적 문법과 click 이벤트의 버블링을 활용하여 클릭 기능을 확장하는 패턴을 사용하면 어떨까요?

<StopPropagation>
  <LogEvent name="프로모션_버튼_선택">
    <Button 
      onClick={async () => {
        await submit()
      }}
    >
      이것은 프로모션 버튼입니다.
    </Button>
  </LogEvent>
</StopPropagation>

클릭 이벤트가 버블링되기 때문에 HTML 엘리먼트를 중첩시켜놓으면 클릭 이벤트 처리를 각 엘리먼트에 위임할 수 있습니다. 결국 기존의 코드를 수정하지 않으면서 새로운 기능을 추가할 수 있는 OCP를 만족하는 코드가 됩니다.

단점

HTML 엘리먼트 중첩에 의존하는 패턴이기 때문에 버튼 하나를 구현할 때 HTML 뎁스가 아주 깊어질 수 있습니다. 예를 들어 위 예시의 렌더링 결과는 다음과 같습니다.

<div onClick={stopPropagation}>
  <div onClick={logEvent}>
    <button>이것은 프로모션 버튼입니다.</button>
  </div>
</div>

giwan-dev avatar Jan 10 '22 08:01 giwan-dev