I am making a small audio player application and attempting to convert my react class component into a functional component.
The original code for the class component is here:
class Player extends React.Component {
constructor(){
super()
this.state = {
tracks: [
{title: "first track", data: track1},
{title: "second track", data: track2},
{title: "third track", data: track3},
],
currentTrack: 0,
}
}
changeData(trackIndex){
this.setState({currentTrack: trackIndex})
}
render(){
return <div style={{color: this.props.color}}>
<h1>Player</h1>
<AudioPlayer
src= {this.state.tracks[this.state.currentTrack].data}
/>
<div style={{color: "green"}}>
<ul>
{this.state.tracks.map((trackElem, index) => (
<li onClick={()=> this.changeData(index)}>{trackElem.title}</li>
))}
</ul>
</div>
</div>
}
}
I have attempted the conversion below:
const Player2 = () => {
const Items = [
{title: "first track", data: track1},
{title: "second track", data: track2},
{title: "third track", data: track3},
];
const [activeTrack, setActiveTrack] = useState(0);
function ChangeData(trackIndex) {
setActiveTrack({activeTrack : trackIndex});
}
return (
<div >
<h1>Player</h1>
<AudioPlayer
src= {activeTrack.data}
/>
<div >
<ul>
{Items.map((trackElem, index) => (
<li onClick={()=> ChangeData(index)}>{trackElem.title}</li>
))}
</ul>
</div>
</div>
)
}
Aside from removing some of the props that are associated with styling the logic is basically the same. The only difference is the handling of the current track, I have attempted to represent this by using states.
When rendering the object to a different page it appears to the screen completely fine, the only issue is that the tracks themselves no longer trigger a response in the audio player.
Would really appreciate it if someone could identify anything I've missed in making the conversion?
Here:
const [activeTrack, setActiveTrack] = useState(0);
So activeTrack
is a number in state initially. But then you do
src= {activeTrack.data}
which doesn't make sense - the number doesn't have a data
property. Another problem is
setActiveTrack({activeTrack : trackIndex});
Now you're setting the active track to an object with an activeTrack
property, which is different from the above two formats as well.
Pick one way to represent, set, and retrieve state throughout the component, such as the index:
function ChangeData(trackIndex) {
setActiveTrack(trackIndex);
}
<AudioPlayer
src={Items[activeTrack].data}