javascript - 状态变量范围无访问反应时间间隔
问题描述
我正在尝试访问 timeInterval 函数内的 intervalId“useState”变量。但是范围不能正常工作。在 timeInterval 函数中,intervalId 始终为 null,这意味着它与值分配的延迟无关。
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))
}
}
}
谢谢你,最好的。
解决方案
IntervalId 是从闭包中使用的,这就是为什么当 setInterval 运行时,值在声明时采用。但是 setIntervalId 会触发状态更新,即使 state 的值已更新, setInterval 函数中的 timerId 仍会继续指向它在关闭时使用的旧状态。
您可以使用 useRef 来存储 timerId,而不是使用 state。由于 refs 发生了变异,因此它们不受关闭的影响
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);
}
}
}
推荐阅读
- python - 熊猫,检查一列是否包含另一列的字符,并标记出字符?
- javascript - 函数中的 JavaScript 事件多次触发
- mongodb - 在mongodb中使用聚合$展开时如何生成对象ID
- xml - ABAP IXML 删除多个空白
- python - 功能圈的范围是什么意思?
- swiftui - 更改 SegmentedPicker 中元素的大小
- powershell - 是否可以通过PowerShell自动将日历约会导出到电子邮件中
- android - 禁用其他子片段的视图寻呼机滑动
- html - 在单独的类上运行 jQuery 函数
- neo4j - 删除前一个节点和关系,指向当前具有相同关系的节点