Реагировать на событие keyDown ИНОГДА, запуская KeyUp

Итак, прямо сейчас в моем приложении 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
  }
}

Давайте посмотрим на JSX.

Randy Casburn 17.02.2019 21:54

@RandyCasburn Для этого компонента нет JSX. Он просто отображает null и помещает прослушиватели событий в document.

Nat Homer 17.02.2019 22:07
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
191
1

Ответы 1

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

Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

и

Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."

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

Другие вопросы по теме