Props Pattern

김동하·2023년 3월 11일
21

react

목록 보기
24/31

들어가며

특정 컴포넌트에 props를 overriding 해줘야 하는 경우, props collections 라는 패턴을 사용한다. 디자인 패턴을 배우면 좋은 것이, 전에는 그냥 '아 그 props 몽땅 전개연산자로 넘기는 거'라고 말했다면 props collections라고 말하면 되니 더 편리하다고 해야 하나... (뭔가 전문가 같아 보인다)

그럼 예제를 살펴보자

Props Collections

토글 버튼이 있는데 1. on 버튼을 누르거나 2. 토글 자체를 누르면 on/off가 변한다.

로직은 useToggle에서 관리하고

UI는 이렇게 구성된다. 이때, 공통으로 적용할 속성을 추가해서 props로 내려준다고 하자. 그러면 <Switch><button>에 매번 작성하는 것은 매우 번거러울 터

'aria-pressed' 속성을 공통으로 추가했다. 이런 식으로 새로운 객체를 return에 담고, overriding 할 속성을 추가한다.

이렇게 되면 관리 포인트가 분산되지 않아 컴포넌트 관리가 용이해진다.

Props Getter

지금 두 컴포넌트 Switch<button>onClick: Toggle을 공통으로 받고 있다. 그런데 만약 해당 기능을 유지하면서 <button>을 클릭했을 때만 다른 기능을 해야한다면 어떨까? 예를들어 GTM이 있을 수 있고, 무언가 다른 추가 액션이 있을 수 있다.

이렇게 되면 overriding이 되지 않아 button을 누르면 토글이 되지 않고 콘솔만 출력된다.

그렇다면 아래와 같이 onClick을 했을 때 togglerProps에서 onClick을 호출하면서 해결할 수 있다.

하지만 이러한 경우는 이벤트가 props의 onClick에 종속되어서 만약 onClick이 아닌 다른 이벤트(onKeydown 등)으로 변경 시 양쪽을 모두 변경해야 하는 번거로움이 있다. 이런 경우는 진짜 빈번하다!!(나는 그랬음...)

이러한 문제를 Props Getter로 해결할 수 있다.

Props Getter의 핵심은 props를 객체가 아닌 함수로 전달하면서 함수의 인자로 자식의 속성을 부모에게 전달하는 것이다. 이렇게 되면 두 컴포넌트의 느슨한 결합이 가능해진다.

getTogglerProps()라는 함수를 받고 자식 쪽에서 함수의 인자로 필요한 인자를 넘긴다. 버튼의 경우 onClick을 했을 때 토글이 on/off 하는 것 외에 콘솔이 찍혀야 하므로 console.log()를 호출하는 함수를 담아서 넘긴다.

로직을 관리하는 useTogglegetTogglerProps() 를 살펴보면 매개변수를 받아서 추가된 props를 합성하여 return하는 함수다.

이때, onClick이 있다면(자식으로부터 받은) onClick을 호출하고 아니면 toggle()을 기본적으로 호출하는 onClick을 속성으로 return하면 된다.

이렇게 토글 스위치를 누르면 기본적인 토글 동작을 하게 되고 버튼을 누르면 기본적인 토글 동작외 추가적인 동작이 가능하다. 필요한 부분을 자식 쪽에서 수정하면 되기 때문에 굉장히 유연해진다.

** 타입 작성하는 거 굉장히 힘들다...

further

하지만 우리 존경하는 kentcdodds 선생님은 여기에 만족하지 않는다. 나는 충분히 만족스럽지만(매번 '여기서 만족하시면 멈추셔도 되지만...' 이라고 하신다) 선생님이 만족하지 않으니 무엇이 문제인지 살펴보자

getTogglerProps 함수에서 onClick 시 작동해야 할 액션을 정의하는 속성에서 만약 이벤트가 많아 진다면 코드가 더러워질 것이다. 좀 더 화끈한 추상화가 필요하다. 이것을 어떻게 해결해야 할까

갑분커링

바로 커링을 이용하는 것이다. callAll은 커링을 적용했는데 커링이란 받아둔 함수들을 원하는 시점에 평가하도록 하는 보조함수이다. 커링이 여기에 쓰이는구나 진짜 미쳤네...

getTogglerPropscallAll의 인자에 함수들을 넘겨주면 callAll이 인자로 들어온 함수가 있다면 차례대로 호출할 것이다. 커링 살짝 설레는 거 같다.

짜잔

참고 -

https://kentcdodds.com/blog/how-to-give-rendering-control-to-users-with-prop-getters

profile
프론트엔드 개발

2개의 댓글

comment-user-thumbnail
2023년 3월 14일

좋은 내용 잘 읽었습니다!!

1개의 답글