0516 올바른 AI 사용법
문제상황: 날짜를 고를 수 있는 DatePicker에 초기화 버튼을 숨겨야하는 기능이 필요하게 되었다
첫 시도: 기존 코드에서 X버튼 노출 조건에 선택값 초기화 후 핸들러인 onClear 선언 유무를 추가해 X버튼 노출을 컨트롤하고자 함
const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
{
onClear, // onClear?: () => void;
},
ref
) => {
return (
<Popover>
<Popover.Trigger>
...
<div className="absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1">
{value && !disabled && onClear && (
<Button>
<XIcon />
</Button>
)}
</div>
</Popover.Trigger>
</Popover>
)
}
이 시도의 문제점:
- onClear는 X버튼 클릭 이후 수행되어야할 로직을 담는 목적의 그릇인데, 그릇이 비어있다고 X버튼을 안보여주는게 넌센스였음
- 모든 DatePicker 구현부에서 의미없는 onClear를 선언해줘야만 X버튼을 노출시킬 수 있는데, X버튼을 숨겨야하는 곳보다 써야하는 곳이 압도적으로 많아 불필요한 코드 양산을 야기함
- 코드 외적으로 꼭 지우지 못하게 선택권을 빼앗아야할까? 에 대한 근본적인 고민이 선행돼야했음
이 리뷰를 받고 처음에 말 뜻을 이해하지 못해서 이해하지 못한 포인트들을 콕 집어서 되물어봄
AI 덕분에 제대로 이해할 수 있게 됨
그래서 아래와 같이 방향을 틀었다
const DatePicker = forwardRef<HTMLButtonElement, DatePickerProps>(
{
onClear,
hideClear = false, // hideClear?: boolean;
},
ref
) => {
return (
<Popover>
<Popover.Trigger>
...
<div className="absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1">
{value && !disabled && !hideClear && (
<Button>
<XIcon />
</Button>
)}
</div>
</Popover.Trigger>
</Popover>
)
}
- hideClear 속성을 추가해 정말 X버튼을 끄고 싶은 경우에만 명시적으로 off해줄 수 있게 함
효과:
- 50여개의 파일 수정에서 2개 파일 수정으로 영향 범위 축소
- 훨씬 직관적인 변경, 미래 유지보수 포인트도 응집되고 간결해짐
얻은 교훈:
- 다시 한 번 UI 컴포넌트는 순수하게(외부 요구사항에 관계없이) 목적에 맞는 기능을 제공하도록 지켜줘야 함
- 특수 상황에 대한 처리(예를 들면 필수값)는
- UI 컴포넌트가 아니라 이를 활용하고 있는 사용처(예를 들면 form 레벨)에서
- 각자 제어하도록(날짜가 필수값이라면 submit하기 전 validating 단계에서 필수값 확인 및 제어) 하여
- 레이어간 경계가 허물어지고 서로 침범하게 놔두면 안됨