2023년에 교내 IT동아리 부원이 되었다. 최근에 다시 웹파트장을 하면서 부원들에게 과제로 나가는 코드를 검토해봤는데 3년 전이랑 다른 관점으로 리팩토링할만한 거리들이 생겨서 적어본다. 그 당시에는 SOLID 원칙을 최대한 지킨다는 이유로, 간결한 컴포넌트 이름을 유지한다는 이유, 컴포넌트 내부 동작이 너무 노출된다는 이유 등으로 내부를 최대한 숨기는 코드를 작성했는데, 지금은 숨길 건 숨기고 드러내야 된다는 관점을 가지게 되었다.
ProductRowList 컴포넌트의 제거
ProductRowList 컴포넌트는 products를 입력 받아서, map 함수를 통해 ProductRow를 렌더링하는 컴포넌트이다.
문제점
디테일을 숨기고 핵심만 드러내는 게 추상화의 이점인데 ProductRowList는 디테일이 없다. 단순히 map을 통해 컴포넌트의 배열을 랜더링하는 책임만 있어 RowList라는 이름으로 은닉하는 정보가 없다.
해결방안
ProductRowList 컴포넌트를 제거하고 사용처에서 map으로 직접 렌더링하는 로직을 노출시킨다.
AS-IS
<React.Fragment key={category}>
<ProductCategoryRow category={category} />
<ProductRowList
products={products}
onEdit={onProductEdit}
onDelete={onProductDelete}
/>
</React.Fragment>
export function ProductRowList({ products, ...props }) {
return products.map((product) => (
<ProductRow key={product.name} {...product} {...props} />
));
}
TO-BE
<React.Fragment key={category}>
<ProductCategoryRow category={category} />
{products.map((product) => (
<ProductRow
{...product}
onEdit={onProductEdit}
onDelete={onProductDelete}
/>
))}
</React.Fragment>
ProductRow 컴포넌트 네이밍
문제점
ProductRow는 product를 렌더링하고, 해당 product에 대한 데이터를 수정할 수 있는 인라인 편집 기능까지 관리한다. 그런데 ProductRow라는 이름만 들었을 때 이 컴포넌트가 할 일은 제품을 row의 형태로 보여주는 것까지만 추측할 수 있다. 물론 onEdit, onDelete라는 이름을 통해 고유의 입력 상태가 있는 인터렉티브한 컴포넌트라는 것을 예측할 수 있지만, ProducRow의 prop 목록을 확인하면서 추측할 수 밖에 없기에 불분명하다고 생각한다.
해결방안
컴포넌트 이름을 ProductRow에서 EditableProductRow으로 변경한다.
EditableProductRow의 prop 이름 onEdit => onSave로 개선
문제점
EditableProductRow는 인라인 편집을 지원하는데, 편집이 끝날 경우 호출하는 함수라는 의미에서 onEdit으로 콜백 함수 이름을 지었다. 그런데 임시 상태가 있고, 이를 save action을 통해서 영구적인 상태로 변환할 때 실행되는 콜백 함수이기에 onEdit이라는 이름만으로는 save action시 호출되는 함수라는 것을 예측하기가 어려운 거 같다.
해결방안
onSave를 onEdit으로 변경한다. save action이 발생할 때 호출되는 함수라는 의미에서 onSave가 더 적합한 거 같다.
AS-IS
export default function ProductRow({ id, name, price, onEdit, onDelete }) {
...
}
TO-BE
export default function EditableProductRow({ id, name, price, onSave, onDelete }) {
...
}
Top comments (0)