Из редюссера я получаю номер текущей песни.
Затем я создаю функцию, которая визуально ставит на паузу предыдущую песню.Этот колбек я создаю при каждом изменении номера песни ( так же я пробовал создавать его единожды, но и это не решало проблему).
Дальше я единожды среди всех рендеров вешаю событие 'ended'. В этом событие я вызываю колбек. Мне нужно, чтобы в колбеке был номер текущей песни, который меняется от рендера к рендеру. 
Я испытал пару способов: пробовал вызвать колбек, передавая в него номер:
() => {listenerEnd(MusicPanel)}
Также я пробовал дать функции получать MusicPanel из окружения (код ниже), но и это не помогло. Во всех этих случаях колбек вызывался с изначально заложенным окружением.
//Мой текущий код(выбрал только нужные куски)
export const TopPanel = memo(() => {
const /*...*/ MusicPanel = UseSelectorMusic()/*Мой личный селектор, который получает музыку из редюссера*/;
    const listenerEnd = useCallback(() => {//Тот самый колбек
        try {
            if (MusicPanel.PlayingInSite) {
                console.log(MusicPanel.NumberOFSong);//Изначальное значение
                document.getElementById(`ButtonPauseOFSongInSite${MusicPanel.NumberOFSong - 1}`).style.display = "none";
                document.getElementById(`ButtonPlayOFSongInSite${MusicPanel.NumberOFSong - 1}`).style.display = "block";
            } else {
                document.getElementById(`ButtonPauseOFSongInPost${MusicPanel.NumberOFSong - 1}`).style.display = "none";// 
                document.getElementById(`ButtonPlayOFSongInPost${MusicPanel.NumberOFSong - 1}`).style.display = "block";
            }
            (document.getElementById("SongInSiteAudio") as HTMLAudioElement).src = MusicPanel.Dir;
            (document.getElementById("SongInSiteAudio") as HTMLAudioElement).play();
        } catch (e) {console.log(e)}
       /*...*/
    }, [MusicPanel.NumberOFSong]);
    useEffect( () => {
       /*...*/
        (document.getElementById("SongInSiteAudio") as HTMLAudioElement).addEventListener('ended',
            listenerEnd
        );
    }, []);
Я смог обойти это, передав в функцию useEffect MusicPanel в массив зависимостей. Это помогает, так как я пересоздаю колбек, но появляется новая проблема, а именно обработчиков событий становится в два раза больше после каждого рендера.
Тогда мой код становится похожим на это:
export const TopPanel = memo(() => {
const /*...*/ MusicPanel = UseSelectorMusic()/*Мой личный селектор, который получает музыку из редюссера*/;
    const listenerEnd = useCallback(() => {//Тот самый колбек
        try {
            if (MusicPanel.PlayingInSite) {
                console.log(MusicPanel.NumberOFSong);//Изначальное значение
                document.getElementById(`ButtonPauseOFSongInSite${MusicPanel.NumberOFSong - 1}`).style.display = "none";
                document.getElementById(`ButtonPlayOFSongInSite${MusicPanel.NumberOFSong - 1}`).style.display = "block";
            } else {
                document.getElementById(`ButtonPauseOFSongInPost${MusicPanel.NumberOFSong - 1}`).style.display = "none";// 
                document.getElementById(`ButtonPlayOFSongInPost${MusicPanel.NumberOFSong - 1}`).style.display = "block";
            }
            (document.getElementById("SongInSiteAudio") as HTMLAudioElement).src = MusicPanel.Dir;
            (document.getElementById("SongInSiteAudio") as HTMLAudioElement).play();
        } catch (e) {console.log(e)}
       /*...*/
    }, [MusicPanel.NumberOFSong]);
    useEffect( () => {
       /*...*/
        (document.getElementById("SongInSiteAudio") as HTMLAudioElement).addEventListener('ended',
            listenerEnd
        );
    }, [MusicPanel.NumberOfSong]);/*Теперь я пересоздаю слушатель событий, что раздваивает его после каждого рендера. В JS документации говорится, что при при повтором вызове слушателя событий прошлый затирается, но не в моём случаи, почему-то.*/
Как бы обойти это замыкание?