Как получить и воспроизвести следующий трек?

Это код аудиоплеера на реакте, пытаюсь сделать переход на следующий трек по нажатию на соответствующую кнопку, но выдаёт ошибку "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, но выдаёт ошибку, пробовал разные способы, подскажите, пожалуйста, как правильно перейти на следующий трек в данном коде?


Ответы (0 шт):