날짜 선택기 교차 연동 버그 수정
목차
date-picker에서 start/end 날짜 간 교차 연동 버그를 수정했다. freeMode hint 잔류 문제도 함께 정리. 변경 파일은 뷰/스타일 5개, 스크립트 1개로 숫자만 보면 가볍지만, 실제로 파고든 범위는 생각보다 넓었음.
버그 원인
start/end picker가 독립적으로 동작할 때는 문제없었다. 두 picker가 서로를 바라보며 제약을 거는 구조에서, 특정 조작 순서를 밟으면 잘못된 결과가 나왔음. 기존 로직이 "start를 먼저 설정한다"는 암묵적인 전제를 깔고 있었던 게 근본 원인. 사용자가 end를 먼저 건드리거나, freeMode 상태에서 값을 초기화하는 경로를 제대로 처리하지 않았다.
date-picker cross-link 버그는 보통 이런 형태로 나타난다.
- start > end인 상태에서 렌더링이 튀는 경우
- end를 먼저 설정했을 때 start의 max 값이 갱신되지 않는 경우
- freeMode 전환 후 hint 텍스트가 화면에 잔류하는 경우
이번 건은 두 번째와 세 번째가 복합으로 섞여 있었다. end picker의 min이 start 변경 시 제때 반영되지 않았고, freeMode hint는 조건이 바뀐 뒤에도 남아있었음. 기능이 "완전히 망가진" 수준은 아니어서 지나치기 쉬운 유형인데, 오히려 이런 게 더 오래 살아남는다.
수정 방향
스크립트에서 핵심은 단방향 제약을 양방향으로 바꾸는 것이었다.
// 수정 전: start 기준으로만 end의 min 제약을 걸고 있었음
endPicker.setMinDate(startValue)
// 수정 후: end가 먼저 설정된 경우도 양방향으로 갱신
function syncPickerConstraints(startVal, endVal) {
if (startVal) endPicker.setMinDate(startVal)
if (endVal) startPicker.setMaxDate(endVal)
if (freeMode) {
clearHint()
}
}
실제 코드는 이것보다 복잡하지만 흐름의 핵심은 이렇다. 기존에는 start가 바뀔 때만 end 쪽 제약을 갱신했는데, 역방향 흐름을 추가하고 freeMode 분기를 명확하게 분리한 것.
hint 잔류 문제는 clearHint() 호출 시점이 좁았던 탓이다. picker 값이 변경될 때만 호출했는데, freeMode 플래그가 바뀌거나 picker 자체가 리셋될 때도 hint가 남는 경우가 있었음. 이 부분을 상태 변화 전반에 걸쳐 hint를 재계산하는 방식으로 바꿨다.
뷰/스타일 파일이 5개 바뀐 건 picker를 여러 화면에서 조금씩 다른 방식으로 쓰고 있어서다. 공통 컴포넌트 하나만 건드리면 끝날 것 같지만, 각 화면마다 초기값이나 이벤트 처리 방식이 달랐음. 완전히 추상화되지 않은 구조에서 수정이 퍼지는 건 어쩔 수 없는 비용이다.
검증
수정 후 가장 먼저 한 건 버그를 직접 재현하는 것. 발생하던 정확한 조작 순서로 다시 돌려보고 의도한 대로 동작하는지 확인했다. 그 다음 정상 케이스 - start 먼저 고르고 end 고르는 통상적인 흐름 - 도 깨지지 않았는지 함께 봤음.
| 항목 | 내용 |
|---|---|
| 버그 재현 | 기존 발생 조작 순서로 동일하게 재현 후 정상 확인 |
| 정상 케이스 | start→end 순서, end→start 순서, 값 초기화 모두 확인 |
| freeMode hint | 모드 전환 및 picker 리셋 시 hint 잔류 여부 확인 |
| 화면별 확인 | 수정된 5개 뷰 각각 동작 직접 확인 |
| 중복 패턴 점검 | 동일한 단방향 제약 패턴이 다른 picker에도 있는지 탐색 |
중복 패턴 점검을 따로 챙긴 데는 이유가 있다. 같은 방식으로 만들어진 picker가 다른 곳에도 있으면, 지금은 안 터져도 비슷한 조건에서 같은 버그가 날 수 있음. 실제로 확인해보니 비슷하게 구성된 부분이 있었고, 위험한 케이스는 이번에 함께 정리했다.
화면 단에서 버그로 보이는 것도 파고들면 상태 흐름 문제인 경우가 많다. picker의 value가 틀린 게 아니라, picker 간 제약 조건이 갱신되는 타이밍이 어긋난 것. 증상만 건드리면 비슷한 상황에서 또 돌아온다.
사내 서비스는 기능 하나가 화면 버튼 하나로 끝나는 경우가 거의 없다. 날짜 범위 하나도 상태 머신, 예외 처리, 화면 렌더링이 엮여 있어서 어느 하나만 빠뜨리면 특정 조건에서 이상한 화면이 나온다. 특히 날짜가 조회 범위나 집계 기준으로 쓰이는 화면이라면 숫자 정합성으로 바로 이어지기 때문에 "대충 맞는 것 같다"로 넘기면 나중에 반드시 다시 온다.
커밋 메시지는 "date-picker cross-link 단방향→양방향, freeMode hint 정리"로 남겼다. 무엇을 바꿨는지보다 왜 바꿨는지가 나중에 맥락을 복원하는 데 훨씬 쓸모 있다. 이번처럼 뷰와 스크립트가 섞인 경우, 커밋을 논리 단위로 쪼개두면 나중에 어느 변경에서 깨졌는지 추적하기가 훨씬 쉬워짐. 그 습관을 이번에도 유지했다.
댓글 0
첫 댓글 달아줘.