Reactjs 如何在功能组件中使用动态JS库(wavesurfer.JS)?

Reactjs 如何在功能组件中使用动态JS库(wavesurfer.JS)?,reactjs,typescript,wavesurfer.js,Reactjs,Typescript,Wavesurfer.js,我有以下使用wavesurfer.js的功能性React组件 从React导入*作为React 从“WaveSurfer.js”导入*作为WaveSurfer 从'@fortawesome/react fontawesome'导入{FontAwesomeIcon}; 从“@fortawesome/free常规svg图标”导入{faPlayCircle,faPauseCircle} 从“@fortawesome/fontawesome svg核心”导入{IconDefinition} 接口波形MP

我有以下使用wavesurfer.js的功能性React组件

从React导入*作为React 从“WaveSurfer.js”导入*作为WaveSurfer 从'@fortawesome/react fontawesome'导入{FontAwesomeIcon}; 从“@fortawesome/free常规svg图标”导入{faPlayCircle,faPauseCircle} 从“@fortawesome/fontawesome svg核心”导入{IconDefinition} 接口波形MPLAYERPROPS{ audioUrl:string } const waveormplayer=props:waveormplayerprops=>{ const[playing,setPlaying]=React.useStatefalse const[audioContext,setAudioContext]=React.useStatenew audioContext 常量[波形,设置波形]=React.useStatenull const waveformRef=React.useRef; React.useffect=>{ 中频波参考电流{ const wavesurfer=wavesurfer.create{ audioContext:audioContext, 容器:waveformRef.current }; wavesurfer。在“完成”时,切换播放暂停 wavesurfer.loadprops.audioUrl setWaveformwavesurfer } }, [] 函数切换PlayPause:void{ 如果audioContext.state==挂起{ audioContext.resume } 波形播放暂停 正在玩!正在玩 } 函数状态按钮图标:图标定义{ 如果玩{ 回粪圈 }否则{ 返回游戏圈 } } 回来 } 导出默认波形模板 我认为我可以访问useEffect之外的WaveSurfer对象的唯一方法是使用useState,但是我觉得这不对,因为如果组件中的某些状态发生更改,WaveSurfer组件不应该完全重新渲染,例如用户按下播放/暂停按钮。这让我觉得我的方法不正确


编辑:忘记提到waveform.playpaise失败,因为单击播放按钮时它为空。

我能想到的最好方法是声明const waveform=React.useRefnull并在文件的其余部分使用waveform.current

import React, { Fragment, useState, useEffect } from 'react'
import WaveSurfer from 'wavesurfer.js'
import audioFile from './../assets/sample-wave-file-5MB.wav'

const WaveSurferStatelessForm = () => {
  let [isPlaying, setIsPlaying] = useState(false)
  let [waveSurfer, setWaveSurfer] = useState(null)

  useEffect(() => {
    setWaveSurfer(WaveSurfer.create({
      container: '#waveform'
    }))
  }, [])

  useEffect(() => {
    if(waveSurfer) {
      waveSurfer.load(audioFile)
    }
  }, [waveSurfer])

  const togglePlayPause = () => {
    waveSurfer.playPause()
    setIsPlaying(!isPlaying)
  }

  return (
    <Fragment>
      <div id="waveform" ></div>
      <button onClick={() => togglePlayPause()}>{isPlaying ? '||' : '+'}</button>
    </Fragment>
  )
}

export default WaveSurferStatelessForm
现在设置了waveSurfer对象,我们需要加载音频。此useEffect将运行两次,但仅在设置waveSurfer对象后加载音频,这将是最后一次调用此useEffect。在此之前,waveSurfer对象为空

  useEffect(() => {
    if(waveSurfer) {
      waveSurfer.load(audioFile)
    }
  }, [waveSurfer])
请注意,useEffect将始终在第一次渲染之后运行,然后在传递给[]的任何状态更改上运行。如果没有[],它将在每次渲染后运行。因此,如果waveformRef.current始终存在,则无需检查div是否存在,因为useEffect在第一次渲染后执行。在statefull或class组件中,这类似于componentDidMount

  useEffect(() => {
    if(waveSurfer) {
      waveSurfer.load(audioFile)
    }
  }, [waveSurfer])