서론

최근, 사이드 프로젝트(클론)을 진행하며 했던 고민을 정리해두어야할 것 같아서 적게되었다.
기억을 더듬어 사고의 흐름대로 한번 따라가보려고 한다.

고민의 대상

고민의 시작은 드롭다운의 컨텐츠 관련 컴포넌트였다.

내 고민의
주범이 되었던
코드 조각들

이전에 Refactor쪽에서 다뤘듯, 언뜻 보면 별로 문제가 없어보인다.

근데, 내 주관적인 시점에서는 더 좋아질 수 있을 것 같다고 생각했다.

1. 고민의 시작점: Route 정의가 반복되는 것 같은데, 문제가 있지 않나? 나중에 갯수가 많아진다면?

2. 그렇다면 import가 이 컴포넌트에서 될 필요가 있는가?(관리 책임이 여기에 있나?)
3. 이 컴포넌트에서 맵을 돌려서 렌더링을 해야하는 이유, 또는 정의를 해야하는 이유가 있나?

 

A.1 잘 하면, 공용으로 뺄 것들을 분리할 수 있을 것 같은데?

문제 1번을 바라보면서 고민했다.

"아, 원하는 url + / + id + / + label 꼴인데, url, id, label을 바깥에서 받아서 그냥 리턴하는 함수를 만들자"

-> 저형태로 반복되는 url을 만들어낼때 편하겠다 ->근데 label과 endpoint가 다르면 어떡하지? -> 일단 보류

 

"흠, label이랑 JSX이름이 같네, label을 집어 넣으면 JSX를 리턴하는 function을 만들자 -> label이랑 JSX이름이 다르면 어떡하지?

->

A.1-1번, 배열로 JSX들을 들고 있는다 -> 해당 function call할때마다 전체 배열(지금은 4개지만 추후에 몇개가 될지 모를)다시 만들거나, 전역으로 관리해야함 -> 기각

 

A.1-2번, 어떻게 이름을 넣으면 동적으로 importing해서 JSX를 꺼내오는 방법은 없나? -> lucide-react를 열어보자

이런 형태이고,
이렇게 꺼내지는데..

-> 일단 동적 import 안됨, 방법이 있을지 모르나 내 지식선에서 해결 불가 -> 꺼내지게 하려면, 저 선언들 중 사용할 것들을 다 꺼내놓고name + Icon형태로 받아서 찾아쓸 수 있게 해야함 -> 일이 커짐 -> 기각

 

A.1-3 ifelse? 좀.. 찝찝, "요구 사항을 정리하면 label을 집어넣으면, label에 맞는 JSX를 리턴했으면 좋겠다."니까 Switch를 써보자.

className 중복도 거슬리지만, 불확실한 컴포넌트를 props로 던져서 CSS를 다시 입히는 행위를 할 최선의 방법이 생각나지 않았다.

 

이제 이걸 반복시키면 되는데, 어떻게 할까

label을 string으로 받아서 split하거나, 그냥 string[]로 받는 방식이 생각났다.

후자로 선택한 이유는, 쪼개고 집어넣고, 쪼개고 집어넣고 할때 드는 비용보다 n개짜리 배열을 통으로 집어넣는게 수가 커질수록 더 나을 것 같다고 생각이 들었기때문이다. 맵을 사용하는게 좀 찝찝하긴 하지만, 결과적으로 {}[]를 리턴해야하는 건 맞으니까 괜찮다고 생각했다.

 

보류한 url로 돌아와서, 현 시점에서 특이한 사항은 board의 경우 아무것도 붙지 않는다는 것이고 예측되는 특이사항은 앞서 말했듯 label과 endpoint가 다를 경우이다. 그리고 고려사항은 label을 lowcase로 변환해야한다는 것이다.

 

따라서, suffix(endpoint)를 받았을때, 
Board면 ? endpoint없이 `${url}/${id}` : `${url}/${id}/${toLowCase()`
여기에 추후 다를 경우 추가되면 switch해서 변환한 것을 꺼내오거나 변환하는 과정을 추가하자고 결정했다.

현시점에서는 board일 확률 < board가 아닐 확률이니  

return suffix !== "Board" ? `${url}/${id}/${suffix.toLowerCase()}` : `${url}/${id}`

로 처리함.

A.2,3 관리 책임?

내가 생각했을때 해당 컴포넌트의 주 역할은 컨텐츠인 item을 렌더링하는 것이다.
routes같은 경우 여기서 그려야할 컨텐츠이기때문에 여기서 들고 아래로 내려주는 것이 맞다고 생각했다.
정의나 맵 함수 사용 등은 컨텐츠를 렌더링하는 veiwer역할을 하는 컴포넌트에서 해야한다고 생각했다.
깊이가 깊어지는 것에 대해 고민했지만, 정의에 대한 책임을 분리하는 것이 더 이득이라고 생각했다.

따라서, 이 컴포넌트에서는 위 내용을 정의하지 않는 것이 좋고, lucide-React의 icon들도, useRouter, usePathname, AccordionContent and Trigger등도 존재하지 않아도 된다고 생각했다.

 

결과물

1. isActive,Expanded, onExpand, organization 등은 드롭박스보다 더 위인 organization에 존재해야함으로 props로 받는 것이 타당.

2. Routes의 요소는 navitem의 컨텐츠이기때문이 해당 컴포넌트 안에 존재하고, props로 내려주는 것이 타당.

 

3. Trigger, Contents, Item에 필요한 요소들은 props로 전달하고 세부 정의는 아래 컴포넌트에서 하는 것이 타당. 

4. route를 브라우저 히스토리에 push하거나, pathname을 사용하는 것들은 Contents안에서만 하는 것이기때문에 Contents로 이동

5. Trigger에서 필요한 것들도 Trigger에서만 사용되도록 이동

 

끝!

 

+ Recent posts