I have a simple music web app that changes the music and image cover onClick, the problem is when I click on a song, the cover image change correctly but the audio source does not play (the src attribute set correctly but it is not playable)
import React, {useState, useEffect} from "react";
const App = () => {
const [songs, setSongs] = useState([]);
const [playing, setPlaying] = useState({});
const server_url = `http://localhost:8765`;
useEffect(() => {
fetch(server_url)
.then(res => res.json())
.then(jsonRes => {
setPlaying(jsonRes.songs[0]);
setSongs(jsonRes.songs);
});
}, []);
return (
<div>
<div>
<img src={`${server_url}/music/imgs/${playing.img}`} width="200" height="200" />
<audio controls>
<source src={`${server_url}/music/mp3/${playing.mp3}`} type="audio/mpeg" />
Your browser does not support the audio element.
</audio>
</div>
<div>
<ul>
{
songs.map(song => {
return (
<li key={song.id} onClick={() => setPlaying(song)}>{song.name}</li>
)
})
}
</ul>
</div>
</div>
);
}
export default App;
The response from the localhost:8765 is like this:
{"songs":
[
{"id":1,"name":"Hello","singer":"Adele","img":"adele.png","type":"pop","mp3":"Adele.mp3"},
{"id":2,"name":"de una vez","singer":"Selena gomez","img":"selena.png","type":"pop","mp3":"Selena.mp3"},
{"id":3,"name":"Bayda","singer":"Navid","img":"navid.png","type":"pop","mp3":"Navid.mp3"},
{"id":4,"name":"Takin' Back My Love ","singer":"Enrique Iglesias","img":"enrique.png","type":"Pop","mp3":"Enrique.mp3"}
]
}
Your React container component will initially render with a broken image and audio player. The audio player doesn't recover so the second audio source
element doesn't load correctly
return
statement after the useEffect
. When songs
is an empty array (which you set as default on line 4) then return
a spinner or return
null (React will not render the component, it's basically skipped). OR secondary solution is to set better defaults on line 4 to be an image and song that has a valid path so it will load before the long running fetch data call.<audio controls autoplay>
)try
/ catch
inside your useEffect
so server errors are caught and handled. To prevent your component from crashing