금융계산기 슬라이더와 숫자 입력, 값이 튀는 이유
슬라이더와 숫자 입력을 양방향으로 묶으면 값이 튀는데요, 원인 세 가지와 프론트엔드에서 안정적으로 동기화하는 방법을 정리했어요.
금융계산기 슬라이더와 숫자 입력, 값이 튀는 이유
대출이나 저축 계산기를 만들다 보면 슬라이더와 숫자 입력창을 나란히 두게 돼요. 슬라이더를 당기면 숫자가 바뀌고, 숫자를 직접 치면 슬라이더가 따라오는 그림이요. 그런데 이걸 양방향으로 묶는 순간 값이 튀기 시작해요. 슬라이더를 살짝 움직였는데 입력창 숫자가 확 뛰거나, 3,150,000을 쳤는데 3,200,000으로 바뀌어 버리는 식으로요. 혹시 같은 걸 겪고 있다면, 원인은 대개 세 가지 안에 들어가요.
원인 1 — step 단위와 자유 입력의 충돌
슬라이더에는 보통 step이 있어요. 10만원 단위처럼요. 그런데 숫자 입력창은 1원 단위까지 받죠. 사용자가 3,150,000을 입력하면 이 값이 슬라이더로 흘러가고, 슬라이더는 가장 가까운 step인 3,200,000으로 스냅해요. 그 스냅된 값이 다시 입력창으로 되돌아오면서 방금 친 숫자를 덮어써요. 직접 만들어 보니 이게 "값이 튄다"고 느끼는 가장 흔한 장면이었어요.
원인 2 — 두 컨트롤이 서로를 갱신하는 루프
슬라이더의 onChange가 상태를 바꾸고, 그 상태가 입력창을 다시 그리고, 입력창이 또 onChange를 부르는 순환이 생기기 쉬워요. 여기에 200ms 정도 디바운스까지 얹으면 두 컨트롤이 잠깐씩 다른 값을 들고 있는 구간이 생겨요. 이 어긋난 순간에 다음 입력이 겹치면 값이 앞뒤로 흔들려요.
원인 3 — 타이핑 도중의 포맷팅
천 단위 콤마를 붙이려고 매 입력마다 문자열을 다시 만들면, "3,000,00" 같은 미완성 상태가 숫자로 파싱되면서 엉뚱한 값이 튀어나와요. 커서 위치까지 밀리고요.
해결의 핵심은 진실을 하나로
세 원인의 뿌리는 같아요. 슬라이더와 입력창이 각자 값을 들고 서로를 고치려 든다는 점이요. 그래서 저는 이렇게 풀었어요.
첫째, 진짜 값은 숫자 상태 하나만 두고 두 컨트롤 모두 그 하나만 바라보게 했어요. 둘째, 입력창이 타이핑 중일 때 보여주는 문자열은 상태와 따로 관리했어요. 사용자가 치는 동안에는 화면 문자열만 바꾸고, 숫자 상태는 파싱이 성공할 때만 갱신하는 식이요. 셋째, 스냅과 최소·최대 clamp는 매 입력마다가 아니라 onBlur 같은 커밋 시점에 1회만 걸었어요. 이렇게 적용해 봤더니 타이핑 중에는 값이 튀지 않고, 손을 뗐을 때만 깔끔하게 step에 맞춰졌어요.
돌려 보니 파싱은 "숫자와 소수점만 남기기 → 정수로 변환 → 범위 밖이면 자르기" 3단계면 충분했어요. 슬라이더는 항상 이 정리된 숫자를 받으니 되돌아오는 값이 입력을 덮을 일이 없고요.
- 단일 상태 하나
- 표시 문자열 분리
- 스냅은 커밋 시점 1회
마무리
테스트해 보면 결국 규칙은 단순해요. 두 컨트롤을 대등한 입력원으로 두지 말고, 숫자 상태 하나를 진실로 삼아 표시만 나눠 쓰는 거예요. 저는 플랜씨(plan-c) 금융계산기를 다듬으면서 이 방식으로 정리했는데, 슬라이더든 키보드든 값이 예측한 대로 움직이니 계산 결과를 믿을 수 있게 됐어요. 값이 튀는 계산기는 사용자가 숫자를 못 믿게 만드니까, 동기화를 하나의 흐름으로 모으는 것부터 손대 보세요.
관련 글
댓글
아직 댓글이 없어요. 첫 댓글을 남겨주세요.