[解決済み] ReactでEscキー押下を検出する方法とその対処法
2022-04-22 06:45:36
質問
reactjsでEscキー入力を検出するにはどうすればよいですか?jqueryと似たようなものです
$(document).keyup(function(e) {
if (e.keyCode == 27) { // escape key maps to keycode `27`
// <DO YOUR WORK HERE>
}
});
検出されたら、その情報をコンポーネントの下に渡したい。3つのコンポーネントがあり、そのうち最後のアクティブなコンポーネントは、エスケープキーが押されたときに反応する必要があります。
コンポーネントがアクティブになったときに登録するようなものを考えていたのですが
class Layout extends React.Component {
onActive(escFunction){
this.escFunction = escFunction;
}
onEscPress(){
if(_.isFunction(this.escFunction)){
this.escFunction()
}
}
render(){
return (
<div class="root">
<ActionPanel onActive={this.onActive.bind(this)}/>
<DataPanel onActive={this.onActive.bind(this)}/>
<ResultPanel onActive={this.onActive.bind(this)}/>
</div>
)
}
}
そしてすべてのコンポーネントに
class ActionPanel extends React.Component {
escFunction(){
//Do whatever when esc is pressed
}
onActive(){
this.props.onActive(this.escFunction.bind(this));
}
render(){
return (
<input onKeyDown={this.onActive.bind(this)}/>
)
}
}
これで動くと思いますが、コールバックのような形になるかと思います。何か良い処理方法はないでしょうか?
どのように解決するのですか?
もし、ドキュメントレベルのキーイベントを処理したいのであれば、以下のようにバインドしてください。
componentDidMount
がベストな方法です(例として
Brad Colthurstのcodepenの例
):
class ActionPanel extends React.Component {
constructor(props){
super(props);
this.escFunction = this.escFunction.bind(this);
}
escFunction(event){
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}
componentDidMount(){
document.addEventListener("keydown", this.escFunction, false);
}
componentWillUnmount(){
document.removeEventListener("keydown", this.escFunction, false);
}
render(){
return (
<input/>
)
}
}
エラーやメモリリークの可能性を防ぐため、アンマウント時にキーイベントのリスナーを必ず削除することに注意してください。
EDIT: フックを使用する場合は、以下のようにします。
useEffect
という構造で、同様の効果を得ることができます。
const ActionPanel = (props) => {
const escFunction = useCallback((event) => {
if (event.key === "Escape") {
//Do whatever when esc is pressed
}
}, []);
useEffect(() => {
document.addEventListener("keydown", escFunction, false);
return () => {
document.removeEventListener("keydown", escFunction, false);
};
}, []);
return (
<input />
)
};
関連
-
[解決済み】TypeError: Router.use() はミドルウェアの関数を要求しているが、Object を取得した。
-
[解決済み】 Uncaught TypeError : undefined のプロパティ 'replace' を読み取れない In Grid
-
[解決済み] 要素外でのクリックを検出するにはどうすればよいですか?
-
[解決済み] JavaScriptのオブジェクトにキーと値のペアを追加するにはどうすればよいですか?
-
[解決済み] Safari、Chrome、IE、Firefox、Operaのブラウザを検出する方法は?
-
[解決済み] React NativeとReactの違いは何ですか?
-
[解決済み] Reactコンポーネントに条件付きで属性を追加するにはどうすればよいですか?
-
[解決済み] Reactコンポーネント外でのクリックを検出する
-
[解決済み] JSX.ElementとReactNodeとReactElementの使い分けは?
-
[解決済み] [ピュアJSやjQueryでエスケープキー押下を検出するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
fetch ネットワークリクエストラッパーの説明例
-
要素ツリー制御によるvueTreeテーブル
-
Vueの要素ツリーコントロールに破線を追加する説明
-
vueにおけるfilterの適用シーンについて解説します。
-
Vueのフォームイベントのデータバインディングの説明
-
[解決済み】Uncaught SyntaxError: JSONの位置0に予期しないトークンuがあります。
-
[解決済み】TypeScript-のAngular Frameworkエラー - "exportAsがngFormに設定されたディレクティブはありません"
-
[解決済み】 `string.split is not a function` というエラーの原因は何ですか?
-
[解決済み】React-Redux: アクションはプレーンオブジェクトでなければならない。非同期アクションにはカスタムミドルウェアを使用する
-
フロントエンド非同期(アシンク)ソリューション(全ソリューション)