nmisr
nmisr

Reputation: 13

Next JS Audio constructor is not defined

I understand why this isn't working but I can't find a solution.

My project has a standard Next JS structure.

I have added a components directory to the root.

Inside components I have the following component:

import { useState } from 'react'

export default function Player({url}) {

    const [audio, setAudio] = useState(new Audio(url))

    return (
      <button onClick={ audio.play() }>Play Audio</button>
    )
}

This (simplified example) component is being imported into one of my pages.

I am seeing the following error: ReferenceError: Audio is not defined

I understand this is because the component is being compiled on the server and NodeJS has no idea what Audio() is.

However I can't find a solution for getting this working.

I have tried importing useEffect and setting the state from within it once the component has mounted but this leads to other errors and I gather is not the correct solution.

Any help on best practices for interacting with browser APIs from within NextJS components would be much appreciated.

**Update: Commenter asked for useEffect implementation

import { useState, useEffect } from 'react'

export default function Player({url}) {

  useEffect(() => {
    const [audio, setAudio] = useState(new Audio(url))
  }, [])

  return (
    <button onClick={ audio.play() }>Play Audio</button>
  )
}

Returns ReferenceError: audio is not defined

Upvotes: 0

Views: 2271

Answers (1)

brc-dd
brc-dd

Reputation: 12954

Your useEffect implementation is wrong. Also, you need to pass a function to onClick. Do something like this instead:

import { useState, useEffect } from 'react'

export default function Player({ url }) {

  const [audio, setAudio] = useState(null)

  useEffect(() => { setAudio(new Audio(url)) }, [])

  return <button onClick={() => { audio?.play() }}>Play Audio</button>
}

Also refer: Rules of Hooks

Here is a CodeSandbox

Upvotes: 1

Related Questions