React keyDown事件SOMETIMES在KeyUp上触发

问题描述 投票:0回答:1

所以现在我在我的React应用程序中发生了一个非常奇怪的现象,我不完全确定如何描述它,但是这里有:

我正在构建一个带有Web Audio API和React的合成器,它响应keyDown事件以触发音符和keyUp事件的开始以触发音符的结束。大部分时间这都完美无瑕。但是,在每10-15人中,一次关键的压力导致在keyDown事件之后发生了额外的keyUp事件。我有一个React组件处理所有事件处理并根据正在处理的事件(keyUpkeyDown)触发Redux操作。另外,当用户持有密钥时,我正在使用lodash/debounce方法来抑制其他keyDown事件。

我不是坚持lodash/debounce功能,我只需要一些东西来抑制额外的keyDown事件。完全有可能我没有正确使用它或者有一个更简单的解决方案。我只需要答案。

我的组件如下:

import React, { Component } from 'react'
import debounce from 'lodash/debounce'

import { REGISTERED_KEYS } from '../constants/keyboard-constants'

export default class ComputerKeyboard extends Component {
  constructor (props) {
    super(props)

    this.handleKeyDown = this.handleKeyDown.bind(this)
    this.handleKeyUp = this.handleKeyUp.bind(this)
  }

  handleKeyDown (e) {
    return debounce((event = e) => {
      if (this.props.currentKeys.indexOf(event.keyCode) < 0 && REGISTERED_KEYS.includes(event.keyCode)) {
        this.props.keyDown(event.keyCode)
        this.props.updateGateStartTime({ value: this.props.audioContext.currentTime })
      }
    }, 2)()
  }

  handleKeyUp (e) {
    const isLastKey = this.props.currentKeys.includes(e.keyCode) && this.props.currentKeys.length === 1
    if (isLastKey && this.props.gateStartTime) {
      this.props.updateGateStartTime({ value: null })
    }
    if (this.props.currentKeys.includes(e.keyCode) && REGISTERED_KEYS.includes(e.keyCode)) {
      this.props.keyUp(e.keyCode)
    }
  }

  componentDidMount () {
    document.addEventListener('keydown', this.handleKeyDown)
    document.addEventListener('keyup', this.handleKeyUp)
  }

  componentWillUnmount () {
    document.removeEventListener('keydown', this.handleKeyDown)
    document.removeEventListener('keyup', this.handleKeyUp)
  }

  render () {
    return null
  }
}
javascript reactjs events web-audio keyevent
1个回答
0
投票

这是debounce。一旦我删除了它,我再也没有看到错误。我试图获得幻想,但不理解节流和去抖动之间的区别。根据这个article

限制强制执行可以随时间调用函数的最大次数。如“每100毫秒最多执行一次此功能”。

Debouncing强制执行一个函数不会被调用,直到一定时间过去而没有被调用。如“只有在没有被调用的情况下经过100毫秒才执行此函数”。

我的想法是,我可能想要节流,并且通过去抖,我允许函数的最后一次调用被允许通过,因为调用之间的时间足够短,偶尔在释放时,debounce让事件通过它应该没有。此外,由于密钥不再被按下并注册,因此handleKeyDown中内置的故障安全逻辑不再适用,因为它预先假定实际存在密钥。

© www.soinside.com 2019 - 2024. All rights reserved.