我正在尝试创建一个带有钩子的计时器,但是当我启动该应用程序时,即使秒数低于0,它仍然只倒数秒。我找不到问题出在哪里
import React, { useState, useEffect } from 'react'
import { Text, View } from 'react-native'
export default App = () => {
const [mins, setMins] = useState(2)
const [secs, setSecs] = useState(2)
useEffect(() => {
setInterval(() => {
if (secs <= 0) {
if (mins <= 0) alert('end')
else {
setMins(m => m - 1)
setSecs(59)
}
}
else setSecs(s => s - 1)
}, 1000)
}, [])
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 40 }}>
{mins}:{secs < 10 && 0}{secs}
</Text>
</View>
)
}
答案 0 :(得分:0)
这应该有效:
别忘了从useEffect
返回并清除clearInterval。
import React, { useState, useEffect } from 'react'
import { Text, View } from 'react-native'
export default App = () => {
const [mins, setMins] = useState(2)
const [secs, setSecs] = useState(2)
useEffect(() => {
const timerId = setInterval(() => {
if (secs <= 0) {
if (mins <= 0) alert('end')
else {
setMins(m => m - 1)
setSecs(59)
}
}
else setSecs(s => s - 1)
}, 1000)
return () => clearInterval(timerId);
}, [secs, mins])
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 40 }}>
{mins}:{secs < 10 && 0}{secs}
</Text>
</View>
)
}
答案 1 :(得分:0)
首先,React.useState
与this.setState
一样,它是一个异步函数,您不应同时调用它们。
其次,React.useEffect
类似于componentDidMount
,componentDidUpdate
,componentWillMount
。您必须在条件不匹配时返回,并清除clearInterval。
我的解决方案代码如下:
import React, { useState, useEffect } from 'react'
import { Text, View } from 'react-native'
export default App = () => {
const [time, setTime] = useState({mins:2,secs:2})
useEffect(() => {
if(time.mins<0){ if(timerId) {clearInterval(timerId)} return}
const timerId = setInterval(() => {
if (time.secs <= 0) {
if (time.mins <= 0) {
setTime({...time,mins:time.mins-1,secs:time.secs})
alert('end')
}
else {
setTime({...time,mins:time.mins-1,secs:59})
}
}
else setTime({...time,mins:time.mins,secs:time.secs-1})
}, 1000)
return () => clearInterval(timerId);
}, [time])
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 40 }}>
{time.mins>=0 ? time.mins : 0}:{time.secs < 10 && 0}{time.secs}
</Text>
</View>
)
}
但是对于本机建议方式,setState
应该在组件中使用,
纯组件不应React.useState
,如果需要,可以使用React。组件