React onKeydown event와 focus에 대한 삽질

React onKeydown Event

React 컴포넌트는 onKeyDown,onKeyUp,onKeyPress(deprecated)keyboard 이벤트를 정의 할 수 있습니다. 이러한 keyboard 이벤트는 아래와 같이 정의하여 쉽게 사용이 가능합니다.

function Input() {
  const handlerKeydown = (e: React.KeyboardEvent) => {
    const {key} = e;
    console.log(key);
  };
  return <input type="text" onKeyDown={handlerKeydown} />;
}

속성 값
altKey : boolean = Alt 키 입력 여부
charCode : number = [Deprecated]
ctrlKey :boolean = Control 키 입력 여부
getModifierState(key) : boolean = Caps Lock, Fn 키 등이 켜져 있는지의 여부
key : string = 사용자의 입력키 정
keyCode : number [Deprecated]
locale : string
location : number = 입력 키의 위치 정보(shift 왼쪽 1 , 오른쪽 2)
metaKey : boolean = windows 의 win 키, mac의 command 입력 여부
repeat : boolean = 키가 반복되서 입려되는지 여부(press 대용을 사용가능)
shiftKey : boolean = shift 키 클릭 여부
which : number [Deprecated]

대부분 input 컴포넌트에 할당하여 사용할 것입니다.

그렇지만 간혹 div 와 같은 Element에 이벤트를 부여해야하는 경우가 있습니다.

이 경우에는 웹접근성을 위하여 tabIndex를 할당 해주시는게 좋습니다.

tabIndex를 지정하지않아도 keyboard 이벤트가 동작합니다.

const NumberFrame = ({addCalcCode}: {addCalcCode: (n: string) => void}): ReactElement => {
  const handlerKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
    const {key} = e;
    if (NUM_REG.test(key)) {
      e.preventDefault();
      addCalcCode(key);
    }
  };

  return (
    <Container onKeyDown={handlerKeyDown}>
      {NUMBERS.map(num => (
        <Button key={num} value={num} onClick={e => addCalcCode(e.currentTarget.value)}></Button>
      ))}
    </Container>
  );
};

div keyboard 이벤트

css 연습과 리팩토링 연습을 위해 계산기를 만들고 keyboard event를 부여하는 과정에 저의 삽질이 시작이 되었습니다….
지금 생각해보면 당연한 것인데 왜? 라는 생각이 뇌를 잡아먹어버렸죠… :sob:

input Element 에 이벤트를 부여한 경우에는 당연하게도 focus가 된 상황을 인지하지않아도 되었지만
div에 키보드 이벤트를 부여한 경우 focus 가 되지않으면 이벤트를 부여했어도 동작하지 않습니다.

저의 경우 숫자 버튼 Container(div)에 이벤트를 정의하였기 때문에 실제 동작을 위해서는 버튼을 하나 클릭하고 난뒤 부터 동작을 하는 것 이였습니다.

결국에는 document.addEventListener("keydown", handlerKeydown); 를 사용하여 이벤트를 정의하는 것으로 정리하였습니다.

  useEffect(() => {
    document.addEventListener("keydown", handlerKeydown);
    return () => {
      document.removeEventListener("keydown", handlerKeydown);
    };
  }, []);

결론

keyboard 이벤트를 정의할때 focus 에 대한 이해가 부족하고, 이벤트만 할당하면 된다고만 생각하여 문제가 있었습니다. 조금만 생각해보면 input과의 차이로 바로 알 수 있었을텐데 말이죠.


:phone: 글에 대한 긍정적, 부정적 모든 피드백을 환영합니다. 말씀주시고 싶은 내용은 댓글이나 메일로 알려주시면 감사합니다!

© 2023.04 All rights reserved.

Powered by Hydejack v9.1.6