프리온보딩 코스 2번째 과제 중 검색어 입력하고 키보드(위, 아래) 버튼 눌렀을때 이동하도록 하는 기능을 맡았다.
검색어를 입력한 뒤 위 아래로 움직이면 이동은 잘 된다.
active 되는 item index를 state로 만들었고 arrow up, arrow down 이 일어날 때 조작해 주었다.
const [activeItemNum, setActiveItemNum] = useState(-1);
검색창이 처음에는 빈값이므로 실행하지 않다가 검색창에 인풋 입력하고, 키보드 방향키로 위 아래로 내일 때 그 activeItemNum를 감지하고 함수를 짜고 싶었다.
이것은 예전에 리액트 배우다가 패턴이기 때문에 기억해두라고 했던게 생각나서 이용했다.
const mounted = useRef(false);
useEffect(()=> {
if(!mounted.current){
mounted.current = true;
}else{
//ajax 등등.. 실행하고자 하는 코드를 여기에 적으면됨..!!
}
},[바뀌는 값]);
useEffect가 componentDidMount 에서 실행되는 것은 어쩔수 없다. 하지만 아무 동작도 하지 않게 만든다. 실행 된 후에는 업데이트 역할만 하도록하는 것이다.
down 방향키는 커서가 계속 뒷쪽에 있어서 문제 없었는데, up 방향키는 커서가 계속 위쪽에 왔다. 여러 방법을 다 찾아다녔지만 내가 발견한 방법은
e.preventDefault();
up 방향키에 넣어주면 이제 커서가 뒷쪽으로 온다. 키보드 이벤트의 기본 속성이였나보다.
그래서 useRef 를 사용하였다.
<input
...
ref={inputRef}
>
그런데 useRef의 타입 지정하는것이 정말 까다로웠다.
const inputRef = useRef<HTMLInputElement>(null);
찾아봤더니 input 에 ref를 걸려면 위와 같이 하라고 해서 null 로 지정은 해두었는데, 다른 값은 넣을 수 없을까?
useEffect 를 이용해서 스테이트 activeItemNum 가 변할 때 마다 inputRef.current.value 를 활성화된 리스트의 텍스트를 가져와서 검색창 input 에 넣어주었다.
문제는 한바퀴 다 돌았을때, 내가 원하는 검색어로 돌아오게 하고싶은데 그게 잘 안되고 있다.
if (activeItemNum === -1) inputRef.current.value = 원래검색어;
이걸 원하는데 아직도 해결을 못하고 있다.
state 에는 그대로 잘 저장되어있는데 그 state 값을 넣으면(원래 검색어 자리에) undefined 에러가 난다.
이 부분은 팀원들과 공유를 해서 같이 해결해보면 좋을것같다..ㅠㅠ 슬프다
나는 input 에다가 onKeyDown 이벤트를 연결했다.
프로퍼티인 keyCode 를 가져오려고 하는데 저렇게 취소선이 생긴다. 타입스크립트에서는 어떻게 인수에다가 구조분해 할당을 할수있을까, 취소선은 왜 생기는건지 모르겠다 ㅠㅠ
다음날 해결..!!
'keycode' is deprecated
keyCode 는 더이상 사용되지 않는다고 한다.
stack overflow에 질문 결과 keyCode 보다 key나 code를 사용할 것을 권장한다고 한다.
keyCode 를 그냥 key로 바꾸면 되지 않을까 했는데 아니였다. 콘솔에 찍어보니 키를 인식하지 못하였고 알고보니 키가 달랐다.
내가 필요한것은
keyCode === 38,
keyCode === 40
이 두가지였는데 검색해보니
key === 'ArrowUp'
key === 'ArrowDown'
이렇게 바꾸면 된다.
다른키는
https://developer.mozilla.org/en-US/docs/web/api/ui_events/keyboard_event_key_values
요기서 참고해 보도록..
다만, 아직 key property를 지원하지 않는 브라우저도 있다고 한다.
지원하지 않는 브라우저는 key property 는 undefined 를 반환할 것이므로 작동을 안 할수도 있으므로 아래와 같이 쓰는 것이 안전하다.
const handleItemActive = (e) => {
const key = e.key || e.keyCode;
if (key === 'ArrowUp' || key === 38) {
...
}
}
어렵지 않아보여서 금방 할 줄 알았는데 예상치 않은 버그들을 만나서 진짜 시간을 많이 썼다. 연차가 쌓이고 경험도 많이 늘다보면 이런 에러들도 곧장 해결하는 날이 오겠지.. 지금은 배우는 단계니까 많은 시행착오를 겪는것이 좋은것 같다.