Dropdown 키보드 접근성 #109
Seon-K
started this conversation in
Trouble Shooting
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
🐞 문제 상황 (Problem Description)
Dropdown 컴포넌트에서 키보드 접근성을 추가하기 위해 ArrrowDown, ArrowUp키를 활용해 항목 간 포커스를 이동시키려고 했으나, 실제 동작이 반대로 작동되는 문제가 발생했습니다.
ex) 아래 방향키를 클릭했으나 아래로 이동하지 않고 위로 이동하거나 위 방향키를 누르면 아래로 이동하는 것과 같은 현상
문제 발생 코드
💻 환경 정보 (Environment)
🔍 발생 원인 분석 (Investigation)
focusedIndex를useState로 관리했지만, 키보드 이벤트 리스너가 처음 등록될 때의 상태를 참조하는 클로저로 만들어진다고합니다.useEffect외부에서addEventListener로 키 이벤트를 등록했기 때문에, 해당 이벤트 핸들러는 처음 렌더링 시점의 상태(focusedIndex)를 기억한 채 유지됩니다.setFocusedIndex는 비동기적으로 작동하기 때문에, 상태를 즉시 참조해도 반영되지 않은 이전 값일 수 있습니다.focusedIndex를 참조해도, 이는 아직 갱신되기 전의 값일 가능성이 크다고 합니다.이 두 문제가 결합되면서, 포커스 이동 시 현재 가리키는 인덱스와 실제 포커스되는 DOM 요소 간에 불일치 현상이 발생하게 되었습니다.
🛠 시도해본 해결 방법 (Attempts)
❌ focusedIndex만으로 처리 → 이벤트 안에서 값이 stale
✅ useRef로 focusedIndexRef 추가하여 실시간 추적
✅ useEffect로 상태 변경 시 ref에도 동기화
✅ 이벤트 리스너에서는 focusedIndexRef.current 기준으로 포커스 이동
✅ 최종 해결 방법 (Final Solution)
DropdownContext에는 focusedIndex, setFocusedIndex만 공유하고,
focusedIndexRef는 DropdownWrapper 내부에서만 관리합니다.
💡 알게 된 점 (Lessons Learned)
React의 상태(useState)는 비동기이며 이벤트 리스너 내부에서는 최신 상태를 보장하지 않음
useRef는 상태 변경 없이 항상 최신 값을 추적할 수 있는 방법
컴포넌트 외부(DOM에 직접 등록한 이벤트 리스너) 에서 이벤트가 발생할 경우, 내부 상태와의 싱크 문제를 반드시 고려해야 함
Beta Was this translation helpful? Give feedback.
All reactions