Как мне использовать динамическую c JS библиотеку (wavesurfer. js) в функциональном компоненте React? - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть следующий функциональный компонент React, который использует waveurfer. js

import * as React from "react"
import * as WaveSurfer from 'wavesurfer.js'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlayCircle, faPauseCircle } from '@fortawesome/free-regular-svg-icons'
import { IconDefinition } from '@fortawesome/fontawesome-svg-core'

interface WaveformPlayerProps {
  audioUrl: string
}

const WaveformPlayer = (props: WaveformPlayerProps) => {
  const [playing, setPlaying] = React.useState(false)
  const [audioContext, setAudioContext] = React.useState(new AudioContext())
  const [waveform, setWaveform] = React.useState(null)

  const waveformRef = React.useRef();

  React.useEffect(() => {
    if (waveformRef.current) {
      const wavesurfer = WaveSurfer.create({
        audioContext: audioContext,
        container: waveformRef.current
      });

      wavesurfer.on('finish', togglePlayPause)
      wavesurfer.load(props.audioUrl)
      setWaveform(wavesurfer)
    }
  }, [])

  function togglePlayPause(): void {
    if (audioContext.state == "suspended") {
      audioContext.resume()
    }

    waveform.playPause()
    setPlaying(!playing)
  }

  function stateButtonIcon(): IconDefinition {
    if (playing) {
      return faPauseCircle
    } else {
      return faPlayCircle
    }
  }

  return (
    <div>
      <button id="waveformAudioControl" className="button is-large" onClick={togglePlayPause}>
        <FontAwesomeIcon icon={stateButtonIcon()} />
      </button>

      <div ref={waveformRef}>
      </div>
    </div>
  )
}

export default WaveformPlayer

Я думаю, что единственный способ получить доступ к объекту WaveSurfer за пределами useEffect - это использовать useState мне это не кажется правильным, так как компонент WaveSurfer не должен полностью повторно визуализироваться, если некоторые изменения состояния компонента (например, пользователь нажимает кнопку воспроизведения / паузы). Это заставляет меня думать, что мой подход не верен?

Редактировать: забыл упомянуть, что waveform.playPause() терпит неудачу, потому что он нулевой, когда нажимается кнопка воспроизведения.

1 Ответ

0 голосов
/ 07 апреля 2020

Лучшее, что я мог придумать, это объявить const waveform = React.useRef<WaveSurfer | null>(null) и использовать waveform.current в остальной части файла.

...