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钩子的解决方案应该适合你。