# An Mp3 player using React and Redux and the HTML5 web audio API

I built a simple MP3 player with React and now I would like to incorporate Redux to the app as it is getting larger and I feel Redux will help it to be more organized and efficient.

I was wondering can you look through my code and help me with a few questions I have (which you will see shortly).

Firstly I will tell you a bit of information on how the simple React version of the app is working:

I have a state called currentSoundIndex which is initialized to 0 as follows:

   getInitialState: function () {
return {
currentSoundIndex: 0
}
}


and this is the main state which changes throughout the application when various methods are called e.g.

1. goToNextSound- The currentSoundIndex is incremented

2. goToPreviousSound- The currentSoundIndex is decremented

I also have a selectSound method which is called when a sound list item is selected.

<li className="sound-info-area" onClick={props.selectSound.bind(null, i)}>
<span className="sound-title">{sound.title}</span>
<span className="sound-artist">{sound.artist}</span>
</li>


The index of the list item is passed in to the selectSound method and used to set the new currentSoundIndex as follows.

selectSound: function(i){
//if user selects a sound then we should firstly stop the player.
this.stopPlayer();
//set the currentSoundIndex state to be the index of the selected list item
this.setState({currentSoundIndex: i}, () => {
//we need to load the player as a new src has been inserted to the Audio tag after the currentSoundIndex state was updated.
if(this.state.isPlaying){
//if the player is in a state of playing then play the sound
this.playSound();
}
});
}


## The Redux version of the app

Now I am re-arranging the application in order to incorporate Redux and I was wondering can I get your advice on the following:

1. Firstly I'm not sure where I should put the "player" logic. I.e I have the stopPlayer() function in my Action creator. Is it ok to have it there?
2. Also, (in a similar way to the selectSound(i) function in the React version of the app), I have created an Action called selectSound. I have also created a reducer to listen for this action. My question is can I create a callback for when this reducer has finished updating the currentSoundIndex state after the action has occured? So that I can call functions such as loadplayer() and playSound().

Here is my SoundsList component/container

import {selectSound} from '../actions/select-sound';

//When clicking on a sound item the selectSound Action creator function is called in order to update the currentSoundIndex.
//after the currentSoundIndex state is updated we should then load the player again and play the sound.
const SoundsList = function(props) {

return (<div className="scrollable-container scrollable">
<div id="list-of-sounds-container">
<ul id="list-of-sounds">

{props.sounds.map((sound, i) => {
return (<li key={sound.id} className={"sound-list-item " + (props.currentSoundIndex === i ? 'selected' : 'not-selected')}>
<span className="sound-info-area" onClick = {() => props.selectSound(i)}>
<span className="sound-title">{sound.title}</span>
<span className="sound-artist">{sound.artist}</span>
</span>
<button className="btn-inline"><i className="fa fa-heart"></i></button>

</li>
);
})}
</ul>
</div>
</div>

);

}
function mapStateToProps(state){
return{
sounds: state.sounds,
currentSoundIndex: state.currentSoundIndex
};
}
function matchDispatchToProps(dispatch){
return bindActionCreators({selectSound: selectSound}, dispatch)
}

export default connect(mapStateToProps, matchDispatchToProps)(SoundsList);


Action creator-selectSound

export const selectSound = (soundIndex) => {
console.log("you clicked on sound: ", soundIndex);
//firstly stop the player when a new sound is selected
//also will need to call loadPlayer() and playSound() after the currentSoundIndex reducer is updated
this.stopPlayer();
return {
type: 'SOUND_SELECTED',
};
};


Reducer- reducer-current-sound.js

export default function (state=null, action) {
//listen for the action type
//if the action type is SOUND_SELECTED than return the index of the sound that was selected
switch(action.type){
case "SOUND_SELECTED":
break;
//action.payload will be the index of the sound.
}
return state;
}


The following is the code for combining my reducers into one

import SoundsReducer from './reducer-sounds';
import CurrentSoundReducer from './reducer-current-sound';

const allReducers = combineReducers({
sounds: SoundsReducer,
currentSoundIndex: CurrentSoundReducer
});

export default allReducers;