State에 너무 많은 걸 부여하지마세요. 의 이어진 내용입니다.
매 달 첫번째 주에 각자의 주제를 가지고 발표를 하는 개발자 모임이있다.
나의 발표 주제는 저번에 작성한 State에 너무 많은 걸 부여하지마세요. 의 글이였습니다.
발표를 마치고 피드백을 받는 도중 한 천재가 나에게 이렇게 말을 했습니다.
🤷♀️ : State에 왜 handler 함수를 넣어요 ?
기존에 공용으로 사용하고 있던 CustomInput은 배열 형식의 State를 받아 반복문을 통해 input을 렌더링하는 형태였습니다.
문제는 CustomInput 컴포넌트 내에서 반복문을 사용했다는 것이였습니다.
공용 컴포넌트 내에서 반목문을 사용하니 확장성은 말할 것도 없이 안좋았습니다.
저 질문을 받고 생각을 해보니 나의 실수였다는 것을 바로 알 수 있었고 말문이 막히게 되었습니다.
😧 : 맞아요... 그렇게하면 해결되는거였어요...
// 잘못된 기존 방식의 공용 컴포넌트 사용
...
const [filters, setFilters] = useState<Filter[]>(
[
{
name: "filter1",
label: "검색조건1",
type: "input",
value: ""
},
{
name: "filter2",
label: "검색조건2",
type: "autoComplete",
items: [1, 2, 3],
value: ""
},
{
name: "filter3",
label: "검색조건3",
type: "selct",
items: ["조건1", "조건2", "조건3"],
value: ""
}
]
)
return (
<CustomInput inputList={filters} />
)
...
위와 같은 형태로 사용을 하고 있었기에 CustomInput 공용 컴포넌트는 데이터를 전달해주는 곳에서 확정하는 행위에 제약을 받게 됐습니다.
// 잘못된 기존 방식의 공용 컴포넌트 사용
...
const [filters, setFilters] = useState<Filter[]>(
[
{
name: "filter1",
label: "검색조건1",
type: "input",
value: ""
},
{
name: "filter2",
label: "검색조건2",
type: "autoComplete",
items: [1, 2, 3],
value: ""
},
{
name: "filter3",
label: "검색조건3",
type: "selct",
items: ["조건1", "조건2", "조건3"],
value: ""
}
]
)
// filter2 input 옆에 버튼을 넣고 싶을 떄
return (
{filters.map(filter => {
if(filter.name === "filter2") return (
<div>
<CustomInput inputList={filter} />
<Button>난 버튼이야</Button>
</div>
)
})}
)
...
피드백을 반영한 후 위와 같은 형태의 좋은 확장성과 깔끔한 코드로 바꿀 수 있게 되었습니다.
컴포넌트를 설계하는 단계에서 아쉬움이 조금 많이 남았습니다.
웃긴건 다른 공용 컴포넌트는 잘해놨음...
아직 경험과 지식이 부족하는 것을 많이 깨달았고 바쁜 업무 중에도 개발자임을 생각하며 코드 퀄리티에 대한 경각심을 가져야한다고 느꼈습니다.
일이 바빠 기존의 레거시 코드들을 리팩토링 할 시간은 없지만 다행히 비중이 크지 않아서 다행이라고 생각이 듭니다.
일단 동작은 하자나 ~ 한잔해 🍺
이번에 프론트엔드 직군에 동료 분이 새로 오시게 된다면 온보딩 겸 함께 레거시 코드를 변환할 생각입니다.