prosource

reactjs에서 문서 키를 누릅니다.

probook 2023. 3. 4. 15:00
반응형

reactjs에서 문서 키를 누릅니다.

합니다.escape.

_handleEscKey: function(event) {
  console.log(event);
  if (event.keyCode == 27) {
    this.state.activePopover.hide();
  }
},

componentWillMount: function() {
  BannerDataStore.addChangeListener(this._onchange);
  document.addEventListener("click", this._handleDocumentClick, false);
  document.addEventListener("keyPress", this._handleEscKey, false);
},

componentWillUnmount: function() {
  BannerDataStore.removeChangeListener(this._onchange);
  document.removeEventListener("click", this._handleDocumentClick, false);
  document.removeEventListener("keyPress", this._handleEscKey, false);
},

그러나 아무 키나 눌러도 콘솔에 아무것도 기록되지 않습니다.윈도우에서 듣거나 '키 누르기', '키업' 등 다른 케이스로 들으려고 했는데 뭔가 잘못하고 있는 것 같아요.

하면 됩니다.keydown andkeypress.

키 누르기(사용되지 않음)는 보통 문서에 따라 문자 출력을 생성하는 키에만 사용됩니다.

키 누르기(사용되지 않음)

키를 누르고 해당 키가 일반적으로 문자 값을 생성할 때 키 누르기 이벤트가 발생합니다.

키다운

키를 누르면 키 다운 이벤트가 발생합니다.

나도 비슷한 문제가 있었어당신의 코드를 사용해서 수정 방법을 설명하겠습니다.

// for other devs who might not know keyCodes
var ESCAPE_KEY = 27;

_handleKeyDown = (event) => {
    switch( event.keyCode ) {
        case ESCAPE_KEY:
            this.state.activePopover.hide();
            break;
        default: 
            break;
    }
},

// componentWillMount deprecated in React 16.3
componentDidMount(){
    BannerDataStore.addChangeListener(this._onchange);
    document.addEventListener("click", this._handleDocumentClick, false);
    document.addEventListener("keydown", this._handleKeyDown);
},


componentWillUnmount() {
    BannerDataStore.removeChangeListener(this._onchange);
    document.removeEventListener("click", this._handleDocumentClick, false);
    document.removeEventListener("keydown", this._handleKeyDown);
},

방식을 메서드에 createClass를 createClass로 .this는 정의된 각 메서드에 암묵적으로 포함되어 있습니다.

여기에서는 react 컴포넌트 작성의 createClass 메서드를 사용하여 jsfiddle이 동작하고 있습니다.

훅을 할 수 는, 「Resact Hooks」를 사용하는 .useEffect이 때문에 이벤트청취자는 1회만 가입되며 컴포넌트가 마운트 해제되면 정상적으로 가입 해제됩니다.

다음의 예는, https://usehooks.com/useEventListener/ 에서 발췌한 것입니다.

// Hook
function useEventListener(eventName, handler, element = window){
  // Create a ref that stores handler
  const savedHandler = useRef();

  // Update ref.current value if handler changes.
  // This allows our effect below to always get latest handler ...
  // ... without us needing to pass it in effect deps array ...
  // ... and potentially cause effect to re-run every render.
  useEffect(() => {
    savedHandler.current = handler;
  }, [handler]);

  useEffect(
    () => {
      // Make sure element supports addEventListener
      // On 
      const isSupported = element && element.addEventListener;
      if (!isSupported) return;

      // Create event listener that calls handler function stored in ref
      const eventListener = event => savedHandler.current(event);

      // Add event listener
      element.addEventListener(eventName, eventListener);

      // Remove event listener on cleanup
      return () => {
        element.removeEventListener(eventName, eventListener);
      };
    },
    [eventName, element] // Re-run if eventName or element changes
  );
};

에서 인스톨 할 도 있습니다( 「npm」등).npm i @use-it/event-listener- 프로젝트 참조는 이쪽 - 。

그런 다음 컴포넌트에서 사용하려면 이벤트 이름과 핸들러를 전달하는 기능 컴포넌트 내에서 호출하기만 하면 됩니다.를 들어, 「」를 사용하는 는,console.log도망치다

import useEventListener from '@use-it/event-listener'

const ESCAPE_KEYS = ['27', 'Escape'];

const App = () => {
  function handler({ key }) {
    if (ESCAPE_KEYS.includes(String(key))) {
      console.log('Escape key pressed!');
    }
  }

  useEventListener('keydown', handler);

  return <span>hello world</span>;
}

이 질문에 더 관련된 Jt oso의 답변 버전입니다.외부 라이브러리나 API 훅을 사용하여 청취자를 바인드/바인드 해제하는 다른 답변보다 훨씬 간단하다고 생각합니다.

var KEY_ESCAPE = 27;
...
    function handleKeyDown(event) {
        if (event.keyCode === KEY_ESCAPE) {
            /* do your action here */
        }
    }
...
    <div onKeyDown={handleKeyDown}>
...

나도 테이블 가능한 div에 대해 같은 조건을 가지고 있었어.

다음 코드는 items.map((아이템)=>...에 대한 호출에 포함되어 있었습니다.

  <div
    tabindex="0"
    onClick={()=> update(item.id)}
    onKeyDown={()=> update(item.id)}
   >
      {renderItem(item)}
  </div>

나한텐 효과가 있었어!

저는 글로벌 이벤트 청취자를 갖고 싶었고 리액트 포털을 이용하느라 이상한 행동을 했습니다.이 이벤트는 문서 내의 포털모달 컴포넌트에서 취소되었음에도 불구하고 문서 요소에서 트리거되었습니다.

전체 구성 요소 트리를 래핑하는 루트 개체에서 이벤트 수신기만 사용하는 쪽으로 이동했습니다.여기서의 문제는 처음에는 본문이 루트 요소가 아닌 포커스에 집중되어 있기 때문에 트리 내의 요소에 포커스를 맞추면 이벤트가 먼저 발생한다는 것입니다.

제가 선택한 솔루션은 탭 인덱스를 추가하여 자동으로 이펙트 훅으로 초점을 맞추는 것입니다.

import React from "react";

export default GlobalEventContainer = ({ children, ...props }) => {
  const rootRef = React.useRef(null);
  useEffect(() => {
    if (document.activeElement === document.body && rootContainer.current) 
      rootContainer.current.focus();
    }
  });

  return <div {...props} tabIndex="0" ref={rootRef}>{children}</div>
};

웜클론을 코드화하고 키 프레스를 식별하여 기대했던 대로 실행하려고 할 때도 비슷한 문제로 고민했습니다.저의 솔루션은 다음과 같습니다.

import { useCallback, useEffect, useState } from "react";

const [random, setRandom] = useState(0.0);
const [key, setKey] = useState("");

const registerKeyPress = useCallback((e) => {
  setRandom(Math.random());
  setKey(e.key);
}, []);
useEffect(() => {
  if (key === "x") console.log("do something");
  }, [random]);
useEffect(() => {
  window.addEventListener("keydown", registerKeyPress);
}, [registerKeyPress]);

마지막으로 누른 키와 동일한 키를 누르면 아무 일도 일어나지 않기 때문에 실제로 키를 누르는 useEffect() 함수를 트리거하기 위해 난수를 사용하고 있습니다(예를 들어 wordle clone에서는 bloom이라는 단어나 두 글자 이상의 문자를 지우거나 백스페이스를 사용하여 여러 문자를 지웁니다).

** 이로 인해 useEffect 의존관계 배열의 결측값에 대한 경고가 발생합니다.후크를 정리하는 보다 적절한 방법이 있을지도 모릅니다(알고 계신 분은 코멘트해 주세요).하지만, 이러한 경고로 인해 에러는 발생하지 않습니다.다음과 같은 코멘트로 무음화할 수 있습니다.// eslint-disable-next-line react-hooks/exhaustive-deps**

언급URL : https://stackoverflow.com/questions/29069639/listen-to-keypress-for-document-in-reactjs

반응형