Ref 不适用于反应声音

时间:2021-06-07 23:47:43

标签: reactjs react-hooks

在页面加载时出现错误: 失败的道具类型:道具 urlSound 中被标记为必需,但其值为 undefined 失败的道具类型:道具 playStatusSound 中被标记为必需,但其值为 undefined 基本上所有名为“sound”的 ref 的属性都不会应用于 soundobject。

import { useEffect, useRef, useState } from 'react'
import Sound from 'react-sound'

function AudioButton(props) {
  
  let buttonText = props.state ?  'Turn audio off' : 'Turn audio on'
  
  return (
    <button onClick={props.onClick}
      className='absolute bottom-0 right-0 z-10 flex items-center justify-center p-3 m-3 text-white transition-colors ease-in-out bg-blue-600 rounded-md cursor-pointer duration-350 hover:bg-blue-800'
    >
      {buttonText}
    </button>
  )
}

function AmbientSound(props) {
  const sound = useRef()
  useEffect(() => {
    sound.current.url='/sounds/ambientStereoSound.wav'
    sound.current.autoLoad=true
    sound.current.loop=true
    sound.current.volume=100
  }, [])
  if(props.state){
    useEffect(() => {
      sound.current.playStatus=Sound.status.PLAYING
    })
  }else{
    useEffect(() => {
      sound.current.playStatus=Sound.status.PAUSED
    }, [props.state])
    
  }
  return <Sound ref={sound} />
}

export default function PlayAmbientSound() {
  const [audioState, setAudioState] = useState(false)
  return (
    <>
      <AmbientSound state={audioState} />
      <AudioButton state={audioState} onClick={() => setAudioState(!audioState)} />
    </>
  )
}

2 个答案:

答案 0 :(得分:1)

失败的道具类型错误是由于没有将正确的道具传递给 Sound 组件。

如果你看一下 the README,你会发现你分配给 ref.current 的值可以作为 props 传递给组件:

// In your React component:
render() {
  return (
    <Sound
      url="cool_sound.mp3"
      playStatus={Sound.status.PLAYING}
      playFromPosition={300 /* in milliseconds */}
      onLoading={this.handleSongLoading}
      onPlaying={this.handleSongPlaying}
      onFinishedPlaying={this.handleSongFinishedPlaying}
    />
  );
}

如果您将值作为 props 传递而不是将它们分配给 ref,您应该会看到这些警告消失。以下是您可以传递给 <Sound /> 的完整道具列表:https://www.npmjs.com/package/react-sound#props

答案 1 :(得分:0)

根据pat的解决方案我把代码改成这样:

function AmbientSound(props) {
  let state = ''
  if(props.state){
      state = Sound.status.PLAYING
  }else{
      state = Sound.status.PAUSED
  }
  return (
    <Sound
      url='/sounds/ambientStereoSound.wav'
      autoLoad={true}
      playStatus={state}
      loop={true}
      volume={100}
    />
  )
}