我有以下使用 wavesurfer.js 的功能性 React 组件
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()
失败,因为单击播放按钮时它为空。