Реагировать на событие keyDown ИНОГДА запускает KeyUp - PullRequest
0 голосов
/ 17 февраля 2019

Так что сейчас у меня в приложении React происходит невероятно странное явление, и я не совсем уверен, как его описать, но здесь идет речь:

Я создаю синтезатор с помощью Интернета.Аудио API и React, которые реагируют на события keyDown, чтобы инициировать начало заметки, и события keyUp, чтобы инициировать конец заметки.В большинстве случаев это работает безупречно.Но одно нажатие клавиши каждые 10-15 приводит к дополнительному запуску события keyDown после события keyUp.У меня есть компонент React, который обрабатывает все события и запускает действия Redux в зависимости от обрабатываемого события (keyUp или keyDown).Кроме того, я использую метод 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
  }
}

1 Ответ

0 голосов
/ 23 февраля 2019

Это был debounce.Как только я удалил это, я больше никогда не видел ошибку.Я пытался придумать, но не понимал разницы между дросселированием и дебушированием.Согласно этой статье :

Регулирование обеспечивает максимальное количество вызовов функции в течение определенного времени.Как и в «Выполнять эту функцию не чаще, чем раз в 100 миллисекунд».

и

Снятие с принудительной процедуры принудительно запрещает повторный вызов функции до истечения определенного временибез этого называется.Как и в «выполнить эту функцию, только если прошло 100 миллисекунд без ее вызова».

Я думаю, что я, вероятно, хочу регулировать и что, отменив, я разрешил последний вызовфункция, которую нужно пропустить, потому что промежуток времени между вызовами был достаточно коротким, поэтому иногда, после освобождения, отладка пропускала событие, которого оно не должно было иметь.Кроме того, поскольку клавиша больше не была нажата и зарегистрирована как таковая, логика отказоустойчивости, встроенная в handleKeyDown, больше не была адекватной, поскольку она предполагает, что на самом деле задействованы клавиши.

...