Как получить и воспроизвести следующий трек?
Это код аудиоплеера на реакте, пытаюсь сделать переход на следующий трек по нажатию на соответствующую кнопку, но выдаёт ошибку "TypeError: Cannot read properties of null (reading 'action'), как правильно в данном коде воспроизвести следующий трек по нажатию на кнопку?
В redux:
import { createSlice } from "@reduxjs/toolkit";
export const audioPlayer = createSlice({
name: "audioPlayer",
initialState: {
currentSong: null,
nextSong: null,
},
reducers: {
setCurrentSong: (state, action) => {
state.currentSong = action.payload;
},
setnextSong: (state, action) => {
state.nextSong = state.currentSong + state.currentSong;
state.nextSong = action.payload;
},
},
});
export const { setCurrentSong, setnextSong} = audioPlayer.actions;
export default audioPlayer.reducer;
В компонентах аудиоплеера:
import { useState, useRef, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { setCurrentSong, setnextSong } from "../../redux/audioPlayer";
import Like from "../Like";
import { IconButton, stepButtonClasses } from "@mui/material";
import SkipPreviousIcon from "@mui/icons-material/SkipPrevious";
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
import PauseIcon from "@mui/icons-material/Pause";
import SkipNextIcon from "@mui/icons-material/SkipNext";
import styles from "./styles.module.scss";
const AudioPlayer = () => {
const [trackProgress, setTrackProgress] = useState(0);
const [duration, setDuration] = useState(0);
const { currentSong, nextSong } = useSelector((state) => state.audioPlayer);
const dispatch = useDispatch();
const audioRef = useRef();
const intervalRef = useRef();
const startTimer = () => {
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
if (audioRef && audioRef.current.ended) {
dispatch(setCurrentSong({ ...currentSong, action: "pause" }));
} else if (audioRef) {
setTrackProgress(audioRef.current.currentTime);
audioRef.current.duration && setDuration(audioRef.current.duration);
} else {
setTrackProgress(0);
}
}, [1000]);
};
const currentPercentage = duration
? `${(trackProgress / duration) * 100}%`
: "0%";
const trackStyling = `
-webkit-gradient(linear, 0% 0%, 100% 0%, color-stop(${currentPercentage}, #fff), color-stop(${currentPercentage}, #777))
`;
useEffect(() => {
if (currentSong.action === "play") {
audioRef.current.play();
} else {
audioRef.current.pause();
}
}, [currentSong]);
useEffect(() => {
currentSong.action === "play" && startTimer();
});
const onScrub = (value) => {
clearInterval(intervalRef.current);
audioRef.current.currentTime = value;
setTrackProgress(audioRef.current.currentTime);
};
const handleActions = () => {
currentSong.action === "play"
? dispatch(setCurrentSong({ ...currentSong, action: "pause" }))
: dispatch(setCurrentSong({ ...currentSong, action: "play" }));
};
const setVolume = (e) => {
// clearInterval(intervalRef.current);
// audioRef.current.currentTime = value;
// setTrackProgress(audioRef.current.currentTime);
audioRef.current.volume = e.target.value / 100;
};
const nextmusic = () =>{
// if (audioRef) {
nextSong.action === "play"?
dispatch(setnextSong({ ...nextSong, action: "play" })):dispatch(setnextSong({ ...nextSong, action: "pause" }));
}
return (
<div className={styles.audio_player}>
<div className={styles.left}>
<img src={currentSong.song.img} alt="song_img" />
<div className={styles.song_info}>
<p className={styles.song_name}>{currentSong.song.name}</p>
<p className={styles.song_artist}>{currentSong.song.artist}</p>
</div>
</div>
<div className={styles.center}>
<div className={styles.audio_controls}>
<IconButton className={styles.prev}>
<SkipPreviousIcon />
</IconButton>
<IconButton className={styles.play} onClick={handleActions}>
{currentSong.action === "play" ? <PauseIcon /> : <PlayArrowIcon />}
</IconButton>
<IconButton className={styles.next} onClick={nextmusic}>
<SkipNextIcon />
</IconButton>
</div>
<div className={styles.progress_container}>
<p>{
trackProgress < 60 ? (String((trackProgress / 100).toFixed(2)).replace(".", ":"))
: (Math.floor(trackProgress / 60) + ':' + (trackProgress % 60).toFixed(0))
// Math.floor(trackProgress)
//trackProgress = trackProgress / 100 //0.02 // 0.6
// (trackProgress < 0, 59) ? trackProgress : (trackProgress + Math.floor(trackProgress))
}</p>
<input
type="range"
value={trackProgress}
step="1"
min="0"
onChange={(e) => onScrub(e.target.value)}
max={duration ? duration : 0}
className={styles.progress}
style={{ background: trackStyling }}
/>
<audio src={currentSong.song.song} ref={audioRef}></audio>
<p>{
duration < 60 ? (String((duration / 100).toFixed(2)).replace(".", ":")) : (Math.floor(duration / 60) + ':' + Math.floor(duration % 60))
//(duration / 60).toFixed(2)
// duration < 60 ? ((duration / 100).toFixed(2)) : (Math.round(duration / 60) + ':' + Math.round(duration % 60))
}</p>
</div>
</div>
<div className={styles.right}>
<input className={styles.volume}
type="range"
//value={trackProgress}
//step="1"
min={0}
//onChange={(e) => onScrub(e.target.value)}
max={100}
onChange={(e) => setVolume(e)}
//className={styles.progress}
style={{ background: trackStyling }}
/>
<Like songId={currentSong.song._id} />
</div>
</div >
);
};
export default AudioPlayer;
Пытаюсь перейти на следующий трек с помощью функции nextmusic, но выдаёт ошибку, пробовал разные способы, подскажите, пожалуйста, как правильно перейти на следующий трек в данном коде?