ReactでkeyDownイベントを簡単に扱えるHooks「useKey | Rooks」
React
Frontend
この記事のゴール
useKey を使って簡潔に keyDown イベントを扱えるようになる
今回使ったコードはこちらにあります。
React で keydown イベント取得
React アプリでキーボードが押されたときに処理させたい場合は、記述が少し複雑になります。 例として、「Enter」を押したときにカウントアップしていくコードを示します。
こちらの例のコードを使っている人は、branch を main にしてください。(デフォルトです)
import React, { Fragment, useEffect, useState, VFC } from "react";
const App: VFC = () => {
const [count, setCount] = useState(0);
const handleKeyDownEnter = (event: KeyboardEvent) => {
if (event.key === "Enter") {
setCount(count + 1);
}
};
useEffect(() => {
document.addEventListener("keydown", handleKeyDownEnter);
return () => {
document.removeEventListener("keydown", handleKeyDownEnter);
};
}, [count]);
return <Fragment>Count : {count}</Fragment>;
};
export default App;
注目していただきたいのは、ここ。
useEffect(() => {
document.addEventListener("keydown", handleKeyDownEnter);
return () => {
document.removeEventListener("keydown", handleKeyDownEnter);
};
}, [count]);
ポイントは、
useEffect の deps に state を指定しなければいけない
アンマウント時にイベントリスナーを除去しないと余計な計算が発生する
時間があったら、アンマウント時の処理を消してみると、動作がすごく重くなることが確認できるのでやってみることをオススメします!
他にも event.key で押されたキーの条件分岐をしたり、気にする部分が多くコードも長くなってしまいます。
useKey
もっとシンプルに keyDown イベント扱いたいと思い、RooksのuseKeyを使ってみました。
Rooks と useKey
様々な用途に使える Hooks の宝庫、それがRooksです。
私はまだ useKey 以外使ったことがないのですが、今後他にも見て使ってみようと思っています。
まずはインストールしてみましょう。
npm install --save rooks
基本的な使い方は以下の通りです。
import react, { useRef } from "react";
import { useKey } from "rooks"; // useKeyをimport
// 第一引数にkey、第二引数にイベントハンドラを指定
// targetを指定しなければdocument全体がtargetになる
useKey(["Enter"], handleKewDownEnter);
// useRefを使うことでtargetを指定することが可能
const targetRef = useRef();
useKey(["Enter"], handleKewDownEnter, {
target: targetRef,
});
これをふまえて先程の例のコードを書き換えてみましょう。
こちらの例のコードを使っている人は、branch を useKey にしてください。
import React, { Fragment, useState, VFC } from "react";
import { useKey } from "rooks";
const App: VFC = () => {
const [count, setCount] = useState(0);
const handleKewDownEnter = () => setCount(count + 1);
useKey(["Enter"], handleKewDownEnter);
return <Fragment>Count : {count}</Fragment>;
};
export default App;
いかがでしょうか!?
useKeyを使うことでかなりすっきりとしたコードになりますね!
私は、今後 keyDown イベントを扱う際はこれを使っていこうと思います。