Keydown 事件与 React 中的 onClick 不一样
Keydown event not working as same as onClick in React
我正在尝试在
上触发下一个和上一个事件的滑块
- 下一个和上一个点击 或
- 左和右箭头单击
OnClick 事件按预期工作。但是 KeyDown 处理程序没有按预期工作。
它在第一次按键时工作正常,比如递增或递减 1。
但在那之后,它要么变成-1,要么变成+1。
我想,我缺少一些基本概念。请指导我我失踪的地方。
你可以在这里测试:
https://codesandbox.io/embed/zen-goodall-35f17?fontsize=14&hidenavigation=1&theme=dark
import React, {useState, useEffect} from "react"
function App(){
const [curImage, move] = useState(0);
const handleKeypress = (e) => {
console.log("keydown", e.keyCode);
if (e.keyCode === 37) {
leftClick();
} else if (e.keyCode === 39) {
rightClick();
}
};
/* eslint-disable */
useEffect(() => {
document.addEventListener("keydown", handleKeypress);
return () => document.removeEventListener("keydown", handleKeypress);
}, []);
/* eslint-enable */
function leftClick() {
move(curImage - 1);
}
function rightClick() {
move(curImage + 1);
}
return(
<>
<button onClick={leftClick}>prev</button>
{" "}
{curImage}
{" "}
<button onClick={rightClick}>next</button>
</>
)
}
export default App;
您可以使用功能状态更新来访问以前的状态,并使用 useCallback
挂钩进行记忆,这样 useEffect
就不会触发不必要的事情。
import React, { useState, useEffect, useCallback } from "react";
function App() {
const [curr, setCurr] = useState(0);
const leftClick = useCallback(() => {
setCurr((prevCurr) => prevCurr - 1);
}, []);
const rightClick = useCallback(() => {
setCurr((prevCurr) => prevCurr + 1);
}, []);
const handleKeypress = useCallback(
(e) => {
if (e.keyCode === 37) {
leftClick();
} else if (e.keyCode === 39) {
rightClick();
}
},
[leftClick, rightClick]
);
useEffect(() => {
document.addEventListener("keydown", handleKeypress);
return () => document.removeEventListener("keydown", handleKeypress);
}, [handleKeypress]);
return (
<>
<button onClick={leftClick}>prev</button>
{" "}
{curr}
{" "}
<button onClick={rightClick}>next</button>
</>
);
}
这是 stale closure values 的问题。 Ramesh提供的使用useCallback钩子的解决方案应该适合你。
我正在尝试在
上触发下一个和上一个事件的滑块- 下一个和上一个点击 或
- 左和右箭头单击
OnClick 事件按预期工作。但是 KeyDown 处理程序没有按预期工作。 它在第一次按键时工作正常,比如递增或递减 1。 但在那之后,它要么变成-1,要么变成+1。
我想,我缺少一些基本概念。请指导我我失踪的地方。
你可以在这里测试: https://codesandbox.io/embed/zen-goodall-35f17?fontsize=14&hidenavigation=1&theme=dark
import React, {useState, useEffect} from "react"
function App(){
const [curImage, move] = useState(0);
const handleKeypress = (e) => {
console.log("keydown", e.keyCode);
if (e.keyCode === 37) {
leftClick();
} else if (e.keyCode === 39) {
rightClick();
}
};
/* eslint-disable */
useEffect(() => {
document.addEventListener("keydown", handleKeypress);
return () => document.removeEventListener("keydown", handleKeypress);
}, []);
/* eslint-enable */
function leftClick() {
move(curImage - 1);
}
function rightClick() {
move(curImage + 1);
}
return(
<>
<button onClick={leftClick}>prev</button>
{" "}
{curImage}
{" "}
<button onClick={rightClick}>next</button>
</>
)
}
export default App;
您可以使用功能状态更新来访问以前的状态,并使用 useCallback
挂钩进行记忆,这样 useEffect
就不会触发不必要的事情。
import React, { useState, useEffect, useCallback } from "react";
function App() {
const [curr, setCurr] = useState(0);
const leftClick = useCallback(() => {
setCurr((prevCurr) => prevCurr - 1);
}, []);
const rightClick = useCallback(() => {
setCurr((prevCurr) => prevCurr + 1);
}, []);
const handleKeypress = useCallback(
(e) => {
if (e.keyCode === 37) {
leftClick();
} else if (e.keyCode === 39) {
rightClick();
}
},
[leftClick, rightClick]
);
useEffect(() => {
document.addEventListener("keydown", handleKeypress);
return () => document.removeEventListener("keydown", handleKeypress);
}, [handleKeypress]);
return (
<>
<button onClick={leftClick}>prev</button>
{" "}
{curr}
{" "}
<button onClick={rightClick}>next</button>
</>
);
}
这是 stale closure values 的问题。 Ramesh提供的使用useCallback钩子的解决方案应该适合你。