Can I use an HTML5 audio element to play a sound file in a functional component using React Hooks?

Viewed 3796

I built a timer using functional components and React Hooks. When the timer reaches 00:00, an audio clip plays. My current code works using new Audio(). Here's a sample:

const Timer = () => {
   const [myAudio] = useState(new Audio(soundfile));

   const handleBeep = () => {
      myAudio.play();
   }

It works but doesn't pass the FCC test because I'm supposed to use an HTML5 tag. I tried the useRef() hook to select the audio file instead. However, myAudio was not recognized as an Audio object:

   const myAudio = useRef();

   const handleBeep = () => {
      myAudio.play();
   }

return (
   <div>
   <audio id='beep' ref={myAudio} src={soundfile} type='audio'/>
   </div>

I've used ref for tags in class components before and I'm wondering if there is a way to do it with React Hooks in functional components. I would hate to have to totally restructure my code just to pass the test, so any input would be helpful.

1 Answers

As mentioned in the comments, React.useRef returns an object with the following interface:

interface ReactRef<T> {
  current: null | T
}

where T is the type of the value for which you expect to capture a reference. This is mentioned in the docs here.

So the reason myAudio.play() isn't working is that you need to access the ref with myAudio.current.play().

It's also advisable to make sure you handle the null case doing something like

if (myAudio.current !== null) {
  myAudio.current.play()
}
Related