область видимости переменной состояния нет доступа время реакции Интервал - PullRequest
1 голос
/ 30 мая 2020

Я пытаюсь получить доступ к переменной intervalId "useState" внутри функции timeInterval. Но прицел не работает должным образом. intervalId всегда имеет значение null внутри функции timeInterval, это означает, что это не касается задержки присвоения значения.

    export function useLocalCommands(length, id) {
    const [intervalId, setIntervalId] = useState(null)
    const [currentIndex, setCurrentIndex] = useState(10)
    const [timeInterval, setTimeInterval] = useState(Constants.READING.READING_TIME_INTERVAL)

    let pauseReading = () => {
        console.log("pause:" + intervalId)
        clearInterval(intervalId)
    }

    let startReading = () => {
        console.log("play")
        pauseReading()
        if (currentIndex < length) {
            setIntervalId(setInterval(() => {
                setCurrentIndex((index) => {
                    if (index < length) {
                        if (id && index % 40 === 0) {
                            Meteor.call('myBooks.updateIndex', id, index, (err, res) => {
                                // show a toast if err 
                            })
                        }
                        return index + 1
                    } else {
                        console.log("pauseReading: " + intervalId)
                        pauseReading();
                    }
                })
            }, timeInterval))

        }
    }
}

Спасибо, С уважением.

1 Ответ

1 голос
/ 30 мая 2020

IntervalId используется с момента закрытия, поэтому при запуске setInterval значения принимаются во время объявления. Однако setIntervalId запускает обновление состояния, и даже если значение состояния обновляется, ваш timerId в функции setInterval продолжает указывать на старое состояние, которое он использовал после закрытия.

Вместо использования состояния вы можете использовать useRef для хранения timerId. Поскольку ссылки изменяются, закрытие не влияет на них

export function useLocalCommands(length, id) {
    const intervalId = useRef(null)
    const [currentIndex, setCurrentIndex] = useState(10)
    const [timeInterval, setTimeInterval] = useState(Constants.READING.READING_TIME_INTERVAL)

    let pauseReading = () => {
        console.log("pause:" + intervalId.current)
        clearInterval(intervalId.current)
    }

    let startReading = () => {
        console.log("play")
        pauseReading()
        if (currentIndex < length) {
            intervalId.current = setInterval(() => {
                setCurrentIndex((index) => {
                    if (index < length) {
                        if (id && index % 40 === 0) {
                            Meteor.call('myBooks.updateIndex', id, index, (err, res) => {
                                // show a toast if err 
                            })
                        }
                        return index + 1
                    } else {
                        console.log("pauseReading: " + intervalId.current)
                        pauseReading();
                    }
                })
            }, timeInterval);

        }
    }
}
...