问题
I'm trying to make one of those custom useKeyPress hooks, and I want my keydown handler to fire on every individual button press, i.e. holding down a key won't trigger it a million times. I'm trying to do this by having a flag that indicates whether to call the handler, callHandler
- it should only be set to true when the target key is released/the component just mounted. Below is a simplified version of what I'm trying to do:
const useKeyPress = (target)=>{
const [callHandler, setCallHandler] = useState(true);
const keyDown = (e) =>{
if(e.key === target && callHandler){
setCallHandler(false); //This line never seems to work properly???
console.log(callHandler, setCallHandler);
//call the keyDown handler
}
}
const keyUp = (e)=>{
if(e.key === target)
setCallHandler(true);
}
useEffect(()=>{
document.addEventListener('keydown', keyDown);
document.addEventListener('keyup' keyUp);
return ()=>{
document.removeEventListener('keydown', keyDown);
document.removeEventListener('keyup', keyUp);
}
},[]);
}
useKeyPress('a');
My issue is that callHandler is never set to false. That console log immediately after setCallHandler just spams the debug screen with (true, ...) when I hold down the 'a' key, meaning that despite the code block running callHandler is somehow always false. Any ideas as to why this isn't working?
回答1:
Im not sure if i get it right , anyway i made this code hope helps u a bit.
EDIT
Change it to custom hook example, maybe useful for someone in future.
const useKeyEvent = (target) =>{
const [keyTarget,setKeyTarget] = React.useState(target);
const [playedKey,setPlayedKey] = React.useState(null);
const [keyDone,setKeyDone] = React.useState(false);
const keyUp = (e) => {
setPlayedKey(null);
setKeyDone(false)
};
const keyDown = (e) => {
const key = e.key;
if (key !== playedKey) {
if(key === keyTarget){
setKeyDone(true);
}
setPlayedKey(key);
}
};
React.useEffect(() => {
document.addEventListener("keydown", keyDown);
document.addEventListener("keyup", keyUp);
return () => {
document.removeEventListener("keydown", keyDown);
document.removeEventListener("keyup", keyUp);
};
}, [keyUp, keyDown,keyDone]);
return [playedKey,keyTarget,setKeyTarget,keyDone];
}
const App = () => {
const [playedKey,keyTarget,setKeyTarget,keyDone] = useKeyEvent("a");
return (
<div>
<h3 style={{color:keyDone?"green":"black"}}>Press {keyTarget} key ! Key : {playedKey}</h3>
<input type="text" onChange={(e)=>setKeyTarget(e.currentTarget.value)} maxLength="1" value={keyTarget}/>
</div>
)
}
ReactDOM.render(<App/>, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
来源:https://stackoverflow.com/questions/65224029/custom-hook-not-using-usestate-properly