У меня есть следующий функциональный компонент 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()
терпит неудачу, потому что он нулевой, когда нажимается кнопка воспроизведения.