【问题标题】:React native timer with hooks用钩子反应本机计时器
【发布时间】:2020-03-07 01:21:32
【问题描述】:

我正在尝试用钩子制作一个计时器,但是当我启动应用程序时,它仍然只倒计时,即使秒数低于 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>
  )
}

【问题讨论】:

标签: react-native react-hooks


【解决方案1】:

这应该可行:

不要忘记从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>
  )
}

【讨论】:

    【解决方案2】:

    首先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>
      )
    }
    

    但是对于 react-native 建议方式,setState 应该在组件中使用, 纯组件不应该React.useState,如果需要,可以使用 React。组件

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 2020-12-02
      相关资源
      最近更新 更多