はじめに
inputとかtextareaでのkeydownの扱い方の記事はあるけど、
div要素の場合がなかったので、記事を書いてみました。
input, textareaなどでのkeydownの使い方はこちらです。
↓
https://blog.zatsuzen.com/react/keypress/
https://masarufuruya.hatenadiary.jp/entry/2017/09/06/200551
前提
react@16.13.1
typescript@3.9.5
概要
keydownイベントをdiv要素に対して使うのは調べてみると簡単で、
componentDidMountにaddEventListenerで、keydownをListenしてあげるだけです。
componentWillUnmountでListenを解除してあげるのを忘れないようにしましょう。
実際のコード
type Props = {
// Propsの型を定義
isHoge: boolean;
}
class CompanyProfile extends React.Component<Props> {
componentDidMount() {
document.addEventListener(
"keydown",
this.handleKeyDown,
);
}
// removeEventListenerを使って解除するのを忘れない
componentWillUnmount() {
document.removeEventListener(
"keydown",
this.handleKeyDown,
);
}
private handleKeyDown = (e: KeyboardEvent) => {
// たとえば、キーボードの左右キーでしたい時
switch (e.key) {
case "Left": // IE/Edge specific value
case "ArrowLeft":
this.keyboardRight();
break;
case "Right": // IE/Edge specific value
case "ArrowRight":
this.keyboardLeft();
break;
}
};
private keyboardRight = () => {
//なにかやりたい処理
console.log("キーボードの右矢印が打鍵されました。");
};
private left = () => {
//なにかやりたい処理
console.log("キーボードの左矢印が打鍵されました。");
};
Tips
自分がハマったのは、親のComponentからPropsに親のComponentのstateを変更するfunctionを渡していたのですが、
親のstateを変更すると、componentDidMountが走り、
keydownのイベントが発火してしまい、意図しないタイミングで、handleKeyDownのメソッドが発動してしまって苦戦していました。
解決策としては、keydownを使いたいComponentの親Componentのstateやpropsの変更をなくして、
componentDidMountが走らないようにしました。
React hookならuseEffectの第2引数で副作用の適用をスキップできるので、うまくいきそうな気がします。。。
最後に
いかがだったでしょうか?
何か間違ってるとかあれば意見を気軽にいただけますと幸いです。
参考
https://stackoverflow.com/questions/43503964/onkeydown-event-not-working-on-divs-in-react
https://ja.reactjs.org/docs/hooks-intro.html
https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/ja/docs/Web/API/Document/keydown_event