С вашим комментарием, описывающим ваши проблемы с редуксом, и скриншотом Redux dev tools - проблема теперь ясна.
Когда вы добавляете песню, вы просто добавляете ее на верхний уровень магазина, фактически не добавляя ее в список воспроизведения.
Было бы вполне возможно исправить это как есть. В вашем редукторе, вместо того, чтобы добавлять песню, как вы делаете сейчас, , вам нужно добавить ее специально в список воспроизведения. Если вам нужен пример кода, я могу предоставить его.
Тем не менее, я призываю вас провести рефакторинг вашего магазина редуксов - и следовать наилучшим практическим методам нормализованного плоского состояния .
Это означает, что вы хотите иметь два объекта верхнего уровня для своего магазина редуксов.
playlists
songs
Вместо того, чтобы включать все данные о песне в список воспроизведения, вы просто ссылаетесь на идентификатор песни.
Ваши плейлисты будут выглядеть так:
playlists {
1: {
title: 'my playlist'
songs: [1,2,3]}
И песни могут остаться прежними.
Каждый раз, когда вы добавляете песню в список воспроизведения, вы просто добавляете песню, а затем обновляете список воспроизведения новым идентификатором песни.
Другая практика, которую вы можете сделать, чтобы сделать ваш код немного чище, - это использовать mapDispatchToProps, а не определять свои встроенные действия по редуксу. Документы для этого здесь.
#
Чтобы исправить код как есть, главное, что нам нужно сделать, это передать плейлист, в который вы хотите добавить песню. Иначе, как еще мы узнаем, куда поместить песню?
Сначала обновите свое действие в addSongFormContainer, чтобы принять дополнительный аргумент targetPlaylist (в который войдет песня)
addSong = (song, targetPlaylist) => {
this.props.dispatch({
type: 'ADD_SONG',
payload: {
playlist: targetPlaylist
id: Math.ceil(Math.random()*10000),
...song
}
})
}
Использование этого действия теперь требует, чтобы вы передали целевой список воспроизведения. Для краткости я собираюсь жестко закодировать, что песня добавляется в список воспроизведения 1. Я оставлю упражнение по передаче выбранного списка воспроизведения до компонента до вас.
Я очистил handleSubmit, чтобы сделать его более понятным, также переместив песню в ее собственную переменную.
handleSubmit = (event) => {
event.preventDefault()
console.log(this.state);
if (this.state.title && this.state.artist) {
let song = {
title: this.state.title,
artist: this.state.artist,
album: this.state.album
}
let selectedPlayList = 1 //Fix this later :)
this.props.addSong(song, selectedPlayList)
}
}
Теперь последняя проблема - это редуктор.
case 'ADD_SONG':
const index = store.getState().findIndex(playlist => playlist.id ===
action.payload.playlist)
console.log(index) //This should be index 0, after looking up playlist id: 1
const updatedPlaylistSongs = this.state[index].data
updatedPlaylistSongs.push(action.playload.song)
return [
...state.slice(0, index), // All playlists before current
{
...state[index], //The targeted playlist.
...updatedPlaylistSongs //The updated songs
},
...state.slice(index + 1), //All playlists after current
]
Я надеюсь, что редуктор работает для вас, хотя, возможно, потребуется немного поработать - я не привык писать редукторы, работающие с массивами. У меня обычно есть нормализованные данные, что приводит к гораздо более легкой модификации. Я настоятельно рекомендую вам попытаться нормализовать ваш магазин. Прекратите использовать массивы, попробуйте использовать объекты, где генерируется ключ (используйте uuidv4 для создания уникального и случайного ключа). Это значительно упрощает «выбор» того, что вы хотите редактировать / обновлять.
Надеюсь, это поможет!