ms-dred
@ms-dred
Вечно что то не то и что то не так...

Почему теряется интервал (Next.js)?

Может быть кто подскажет что не так делаю.
Стоит задача сделать листаку фоток по клику, для этого на странице есть кнопки Назад/Вперед и кнопка запуска листалки.
Казалось бы все делается на изи, но что то я делаю не так ;)

const PlayPhotoIntervalElementComponent = () => {

    const { store } = useContext(Context)
    const [activePlay, setActivePlay] = useState(false)

    const handlePlay = useCallback((e: any) => {

        const nextFlipping = document.getElementById("nextFlipping")
        const nextButton = nextFlipping?.querySelector("button")

        if (nextButton) {

            let timer = setInterval(() => nextButton?.click(), 5000)

            if (!activePlay) {

                console.log("start")
                setActivePlay(prevState => !prevState)

                return () => {
                    clearInterval(timer)
                }
            } else {
                console.log("stop")
                setActivePlay(false)
                return clearInterval(timer)
            }
        }
    }, [
        activePlay,
        setActivePlay
    ])

    return (
        <div className={stylesPlayButton.container}>
            <button
                onClick={handlePlay}
            >
                {
                    activePlay
                        ? <StopIconComponent viewBox="0 0 24 24" width={32} height={32} />
                        : <PlayIconComponent viewBox="0 0 24 24" width={32} height={32} />
                }

            </button>
        </div>
    )
}


Запуск интервала проходит отлично и все листается как надо, но когда нажимает на кнопку остановки листалки, меняется только ее статус (activePlay), а сама листака продолжает работать в штатном режиме =)
  • Вопрос задан
  • 52 просмотра
Решения вопроса 1
szQocks
@szQocks
при изменении зависимостей, создаётся новая функция в useCallback, в котором создаётся ссылка на новый интервал, ссылка на старый интервал - потеряна

если переменную timer заменить на ref и присваивание setInterval(() => nextButton?.click(), 5000) поместить внутрь второго if, то всё сработает, но лучше бы - логику по интервалу вынести в useEffect, а в handlePlay - менять только флаг стейта
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы