如果按下向右或向左箭头键,下面的组件将设置状态。因为每个按键都会执行两个设置状态,所以会导致一些性能问题。如何在不设置状态或仅设置一种状态的情况下更改按键?
import { useState, useEffect } from "react";
export function useKeyPress(targetKey) {
const [keyPressed, setKeyPressed] = useState(false)
function downHandler({ key }) {
if (key === targetKey) {
setKeyPressed(true);
}
}
const upHandler = ({ key }) => {
if (key === targetKey) {
setKeyPressed(false);
}
}
useEffect(() => {
window.addEventListener("keydown", downHandler);
window.addEventListener("keyup", upHandler);
return () => {
window.removeEventListener("keydown", downHandler);
window.removeEventListener("keyup", upHandler);
}
})
return keyPressed
}
如果您始终需要 的当前值keyPressed
,则无法绕过设置状态,但您可以通过指定依赖项列表并useRef()
像这样调用来跳过效果:
export function useEventListener(targetRef, type, handler) {
const handlerRef = useRef(null);
useEffect(() => {
handlerRef.current = handler;
}, [handler]);
useEffect(() => {
const target = targetRef.current;
const listener = (event) => handlerRef.current(event);
target.addEventListener(type, listener);
return () => {
target.removeEventListener(type, listener);
};
}, [targetRef, type]);
}
然后你可以像这样定义你的函数:
export function useKeyPress(targetKey) {
const [keyPressed, setKeyPressed] = useState(false);
const windowRef = useRef(window);
useEventListener(windowRef, 'keydown', ({ key }) => {
if (key === targetKey) {
setKeyPressed(true);
}
});
useEventListener(windowRef, 'keyup', ({ key }) => {
if (key === targetKey) {
setKeyPressed(false);
}
});
return keyPressed;
}
虽然在targetRef
上面的特定示例中,该参数起初可能看起来很迂回,但它非常有用,例如,当您想将事件侦听器添加到 JSX 元素时,如下所示:
const { useEffect, useRef } = React;
function useEventListener(targetRef, type, handler) {
const handlerRef = useRef(null);
useEffect(() => {
handlerRef.current = handler;
}, [handler]);
useEffect(() => {
const target = targetRef.current;
const listener = (event) => handlerRef.current(event);
target.addEventListener(type, listener);
return () => {
target.removeEventListener(type, listener);
};
}, [targetRef, type]);
}
function App() {
const buttonRef = useRef(null);
useEventListener(buttonRef, 'click', () => {
console.log('button clicked');
});
return (
<button ref={buttonRef}>Click Me</button>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句