首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >KeyDown和keyUp不保存多个密钥

KeyDown和keyUp不保存多个密钥
EN

Stack Overflow用户
提问于 2021-03-25 01:24:31
回答 1查看 33关注 0票数 0

我正在构建一个简单的俄罗斯方块应用程序,在其中我有可以点击的按钮的gameoby。

目前它是一个react应用程序,我处理点击的方式定义如下:

代码语言:javascript
运行
复制
  const [keyPressed, setKeyPressed] = useState([])

  const onKeydown = (e) => {
    const currentKey = e.key.toLowerCase()
    const localKeyPressed = [...keyPressed]
    localKeyPressed.push(currentKey)
    setKeyPressed(localKeyPressed)
  }

  const onKeyUp = (e) => {
    const currentKey = e.key.toLowerCase()
    const localKeyPressed = keyPressed
    localKeyPressed.pop(currentKey)
    setKeyPressed(localKeyPressed)
  }

  useEffect(() => {
    document.addEventListener('keydown', onKeydown)
    document.addEventListener('keyup', onKeyUp)

    return () => {
      document.removeEventListener('keydown', onKeydown)
      document.removeEventListener('keyup', onKeyUp)
    }
  }, [])

我想要一个数组,当我连续按两个键(例如:'A','B')时,我得到的是A,B,目前不是这样的,我只是得到了A,我不知道确切的原因。

关于这个话题有什么帮助吗?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-25 04:28:04

事件处理函数依赖于当前状态keyPressed。当您将它们附加到useEffect中的事件时,这些函数将指向原始的keyPressed状态,这是一个空数组。每当更新状态时,都会将当前值添加到空数组中,并将其设置为新状态。

useEffect依赖项数组为空,因此在卸载组件之前不会再次调用它。一种解决方案是将函数添加到依赖关系数组,以便在每次呈现时添加和删除事件处理程序。另一种选择是避免依赖项的需要。当新状态依赖于前一个状态时,请使用useStatefunctional updates形式,以避免将前一个状态用作依赖项。

此外,不要在onKeyUp中改变状态,因为const localKeyPressed = keyPressed不会克隆原始状态,所以使用数组扩展来完成此操作。

代码语言:javascript
运行
复制
const { useState, useEffect } = React

const Demo = () => {
  const [keyPressed, setKeyPressed] = useState([])

  useEffect(() => {
    const onKeydown = e => {
      setKeyPressed(oldState => [
        ...oldState,
        e.key.toLowerCase()
      ]) 
    }

    const onKeyUp = e => {
      setKeyPressed(oldState => {
        const newState = [...oldState]
        
        newState.pop()

        return newState
      }) 
    }

    document.addEventListener('keydown', onKeydown)
    document.addEventListener('keyup', onKeyUp)

    return () => {
      document.removeEventListener('keydown', onKeydown)
      document.removeEventListener('keyup', onKeyUp)
    }
  }, [])

  return (
    <div>
    {
      JSON.stringify(keyPressed)
    }
    </div>
  )
}

ReactDOM.render(
  <Demo />,
  root
)
代码语言:javascript
运行
复制
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66786184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档