2
\$\begingroup\$

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.
 this.loadPlayer();
 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',
 payload: soundIndex 
 };
};

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":
 return action.payload;
 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;
asked May 27, 2017 at 13:06
\$\endgroup\$

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.