我试图用钩子制作一个计时器,但当我启动应用程序时,它仍然只倒数秒,即使秒数低于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>
)
}
这应该有效:
不要忘记从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>
)
}
首先,React.useState
和this.setState
一样,是一个异步函数,不应该同时调用它们
其次,React.useEffect
类似于componentDidMount
、componentDidUpdate
、componentWillMount
。当您的条件不匹配时,必须返回并清除Interval
我的解决方案代码如下:
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。组件