【问题标题】:When a key is pressed, the event occurs twice当一个键被按下时,事件发生两次
【发布时间】:2021-10-16 01:17:17
【问题描述】:

当我使用 keyEvent 按下一个键时,我会调用该函数,它在下面。

const GeneratedKey: FC<IGenerated> = (props) => {

    const [keyBoard, setKeyBoard] = useState("")
    const [arrayMovie, setArrayMovie] = useState<string[]>([])
    const idPage = props.idpage
    const nameMovie = data.results[idPage].title
    const [idLetter, setIdLetter] = useState<number>(0)
    const [indexArray, setIndexArray] = useState<number[]>([])
    const arrayNameMovie = nameMovie.split(" ").join("").split("");
    
    const getKey = (e: any) => {
        console.log("test")
        const key = e.key
        let count = 0
        for (let i = 65; i <= 90; i++) {
            if (key.toUpperCase() == String.fromCharCode(i)) {
                count = 1
            } else if (key.toLowerCase() == "backspace") {
                count = 10
            }
        }
        if (count == 1) {
            indexArray.sort(function (a: any, b: any) {
                return a - b;
            })
            arrayMovie.splice(indexArray[idLetter], 1, key)
            setIdLetter(idLetter + 1)
        } else if (count == 10) {
            if (idLetter >= 1) {
                setIdLetter(idLetter - 1)
                arrayMovie.splice(indexArray[idLetter], 1, "")
            }
        }
        setKeyBoard(key)
        document.removeEventListener("keydown", getKey);
    }

    useEffect(() => {
        for (let i = 3; i >= 0; i--) {
            const randomIndex = Math.floor(Math.random() * arrayNameMovie.length)
            arrayNameMovie.splice(randomIndex, 1, " ")
            indexArray.push(randomIndex)
        }
        setIdLetter(indexArray[0])
        setArrayMovie(arrayNameMovie)
    }, [])

    document.addEventListener("keydown", getKey)

    return (
        <div className="down__word">
            {arrayMovie.map((letter: any) =>
                <LettersView letters={letter} props={undefined} />
            )}
        </div>
    )
}

其实应该调用一次,但是会触发两次,从console.log();可以看到 我该如何解决这个问题,我也可以用代码显示其他文件,但这不太可能有帮助

【问题讨论】:

  • 在 addEventListener 之前添加一个 console.log 来检查你的组件是否创建了两次
  • @emptyhua 是的,console.log 它工作了两次

标签: javascript reactjs keyevent


【解决方案1】:

这是因为您的组件可能会被渲染两次(由于 props 的更改或任何外部原因)。此外,我认为这不是在 FC 中处理事件侦听器的正确方法。您应该考虑使用useEffect 注册/取消注册事件监听器。

useEffect(() => {
  const handler = () => {};
  document.addEventListener('keydown', handler);
  return () => {
    document.removeEventListener('keydown', handler);
  }
}, [deps]); // if you have any changing dependency else just remove the array to execute the UseEffect everytime.

这将确保您在代码中只注册了一次事件。

参考https://reactjs.org/docs/hooks-effect.html

【讨论】:

  • useEffect 的依赖数组。比如何时执行 useEffect 钩子。遵循官方文档。你会明白的。
  • 感谢您的帮助,但现在我数组中的数据没有改变,具体来说,我的意思是arrayMovie.splice (indexArray [idLetter], 1, key)这一行,您能告诉我更多相关信息吗?
  • 这可能是由于第二个可选参数数组。您可以选择在代码中使用 2 个 useEffect,一个用于事件侦听器(根据您的要求,使用空、填充或根本没有第二个数组参数),另一个用于管理您的数组,其中空数组作为第二个参数。请记住,您需要先了解第二个数组参数的作用。
猜你喜欢
  • 1970-01-01
  • 2020-10-07
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 2013-10-05
  • 2011-12-20
相关资源
最近更新 更多