React Native 中实现倒计时功能

目录
  • 正文
  • 首次实现
  • 最终实现
  • 示例

正文

在 React Native,该如何实现一个倒计时功能呢?

首次实现

表面看来很简单,譬如像下面这样:

const timer = useRef<ReturnType<typeof setInterval> | null>(null)
const [count, setCount] = useState(0)
const start = () => {
  setCount(10)
  timer.current = setInterval(() => {
    setCount((count) => count - 1)
  }, 1000)
}
useEffect(() => {
  if (count === 0 && timer.current !== null) {
    clearInterval(timer.current)
    timer.current = null
  }
}, [count])

这段代码大多数情况下是可以正常工作的。但是你将应用退到后台,稍后再进入看看。

很有可能,原本应该结束的倒计时,还在工作。

这是因为 React Native 应用退到后台后,世界会停止。为了适应这点,我们应该先设定希望倒计时结束的时间,然后每隔一秒计算一次当前时间与结束时间之差(秒)。

此外,当应用退到后台时,应该清除定时器。

最终实现

考虑上述种种,倒计时的实现并不简单。

我们可以封装一个自定义 Hook 来提供可复用的倒计时功能。

import { useAppState } from '@react-native-community/hooks'
import { useCallback, useEffect, useRef, useState } from 'react'
export function useCountdown(seconds = 30) {
  const timer = useRef<ReturnType<typeof setInterval> | null>(null)
  const [target, setTarget] = useState<Date | null>(null)
  const [count, setCount] = useState<number>(0)
  const appState = useAppState()
  const start = useCallback(() => {
    setTarget(add(new Date(), seconds))
  }, [seconds])
  const stop = useCallback(() => {
    setTarget(null)
    setCount(0)
  }, [])
  useEffect(() => {
    if (target === null || appState !== 'active') {
      return
    }
    setCount(diff(new Date(), target))
    timer.current = setInterval(() => {
      setCount(diff(new Date(), target))
    }, 1000)
    return () => {
      if (timer.current) {
        clearInterval(timer.current)
        timer.current = null
      }
    }
  }, [target, appState])
  useEffect(() => {
    if (count === 0) {
      stop()
    }
  }, [count, stop])
  return { count, start, stop }
}
function add(date: Date, seconds: number) {
  return new Date(date.getTime() + seconds * 1000)
}
function diff(now: Date, target: Date) {
  return Math.max(
    Math.trunc((target.getTime() - now.getTime()) / 1000 + 0.5),
    0
  )
}

示例

这里有一个示例,供你参考。

以上就是React Native 中实现倒计时功能的详细内容,更多关于React Native倒计时的资料请关注我们其它相关文章!

(0)

相关推荐

  • react native中的聊天气泡及timer封装成的发送验证码倒计时

    其实,今天我想把我近期遇到的坑都总结一下: 1.goBack的跨页面跳转,又两种方法,一可以像兔哥那样修改navigation源码,二可以用navigationActions 2.父子组件的传值,一可以用callBack  二可以用pubsub发布订阅模式 三可以用manager事件监听(a页面要显示的内容 有两种形式,一是从manager主动接收,也就是说不需要点击什么的获取数据,而是时时监听manager里数据的变化,第二种a页面获取要显示内容的形式是 点击出发,获取) 3 需要说的还是na

  • ReactNative短信验证码倒计时控件的实现代码

    由于最近刚开始认真的搞RN,可能有一些封装的不是最佳实践,还是希望大家多提意见,和大家一起进步吧.本文介绍了ReactNative短信验证码倒计时控件,分享给大家 功能 根据项目的需要,需要写一个自定义的控件,实现如下功能: 默认文字为点击获取验证码 点击后出现60秒的倒计时 颜色,字号可调 倒计时过程中,再次点击需要忽略掉 倒计时完成后文本恢复成点击获取验证码 再几次点击同之前 其实说了这么多,就是个最普通的验证码的功能... 效果 效果图如下:(录的图片比较一般,对付着看吧) 实现原理 自己

  • React Native验证码倒计时工具类分享

    本文实例为大家分享了React Native验证码倒计时工具类的具体代码,供大家参考,具体内容如下 因为以前直接用定时器,没去计算当前的时候,每次退出程序的时候,定时器一直不走,这个工具类简单的解决程序退出后台,定时器不走的bug,那么,直接上代码咯~~ /** * Created by zhuang.haipeng on 2017.9.11 * * 广告倒计时,验证码倒计时工具类 * * 用法: //60 * 1000 为60秒 , 60 * 60 * 100 为60分钟 ... * let

  • React-Native中使用验证码倒计时的按钮实例代码

    开发过程中有获取手机验证码的场景,这时候有这样的要求: 1,点击"获取验证码"的按钮,发起获取验证码的网络请求,同时按钮置为不可用 2,如果网络请求成功,按钮继续不可用,但按钮上文本改为倒计时((*s)后重新获取) 3,如果网络请求失败,按钮置为可用 4,倒计时结束,按钮可用 直接上代码 源码 import React,{PropTypes} from 'react'; import {View,Text,TouchableOpacity} from 'react-native'; e

  • React Native 中实现倒计时功能

    目录 正文 首次实现 最终实现 示例 正文 在 React Native,该如何实现一个倒计时功能呢? 首次实现 表面看来很简单,譬如像下面这样: const timer = useRef<ReturnType<typeof setInterval> | null>(null) const [count, setCount] = useState(0) const start = () => { setCount(10) timer.current = setInterval

  • React Native中Navigator的使用方法示例

    前言 众所周知在React Native中如何实现页面的跳转,这是一个突破点也是一个难点,想让我们的页面切换起来动起来应该是每一个初学者所追求的,那么在RN中实现这样的功能那必须要了解Navigator的用法了.Navigator是React Native自带的组件,不需要导入第三方组件,下面就来具体说明如何使用. 方法如下 首先,我们最好不要把index.ios.js和index.android.js文件写的很冗余很多代码,可以仅仅将其当做是一个工程的入口,好,废话不多说,开始上代码. 1.习

  • React Native中的RefreshContorl下拉刷新使用

    我们知道App中都有下拉加载,在React Native中也有类似的控件 一.属性方法 (1) onRefresh function 在视图开始刷新的时候调用 (2) refreshing bool 视图是否在刷新时显示指示器,也表明当前是否在刷新中 (3) colors [ColorPropType] android平台适用 进行设置加载进去指示器的颜色,至少设置一种,最多可以设置4种 (4) enabled bool android平台适用 用来设置下拉刷新功能是否可用 (5) progre

  • React Native中Android物理back键按两次返回键即退出应用

    前言 本文主要给大家介绍了关于React Native中Android物理back键按两次返回键就会退出应用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 话不多说,直接上图: 测试代码 第16~22行 设置事件监听以及移除事件监听. componentWillMount(){ BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid); } componentWillUnmount()

  • React Native中ScrollView组件轮播图与ListView渲染列表组件用法实例分析

    本文实例讲述了React Native中ScrollView组件轮播图与ListView渲染列表组件用法.分享给大家供大家参考,具体如下: 1.Scroll View ScrollView是React Native提供的滚动视图组件,渲染一组视图,用户可以进行滑动响应交互,其常用属性如下: 滚动的偏移量:通过event.nativeEvent.contentOffset.x可以得到水平偏移量. horizontal={bool},属性为true时,所有子视图在水平方向排列,否则在纵向排列.默认为

  • React Native中实现动态导入的示例代码

    目录 背景 多业务包 动态导入 Metro 打包原理 打包过程 bundle 分析 __d函数 __r函数 方案设计 分 识别入口 树拆分 bundle 生成 合 总结 背景 随着业务的发展,每一个 React Native 应用的代码数量都在不断增加,bundle 体积不断膨胀,对应用性能的负面影响愈发明显.虽然我们可以通过 React Native 官方工具 Metro 进行拆包处理,拆分为一个基础包和一个业务包进行一定程度上的优化,但对日益增长的业务代码也无能为力,我们迫切地需要一套方案来

  • React Native 中添加自定义字体的方法

    目录 添加字体 定义 assets 目录 执行 link 命令 在样式中使用字体 示例 在 React Native 中,如何添加自定义字体呢?React Native 提供了便捷的命令行工具来帮助我们. 添加字体 在项目根目录下创建 assets/fonts 文件夹,把字体文件放到这个文件夹下. 如图: 定义 assets 目录 在项目根目录下创建 react-native.config.js 文件,编辑其中内容,留意第 6 行,这和我们自定义字体文件所在目录一致. module.export

  • 在 React Native 中使用 CSS Modules的配置方法

    目录 安装依赖和配置 使用 示例 有些前端工程师希望也能像开发 web 应用那样,使用 CSS Modules 来开发 React Native.本文将介绍如何在 React Native 中使用 CSS Modules. 安装依赖和配置 首先安装 react-native-sass-transformer 使得我们可以在 React Native 应用中使用 sass 样式. yarn add react-native-sass-transformer sass -D 参考如下配置,修改 me

  • React Native 中处理 Android 手机吞字的解决方案

    目录 复现问题 解决问题 示例 React Native App 在部分型号的 Android 手机上,可能会发生文字显示不全的问题. 官方也有一个 相关的 Issue ,并提供了如下的解决方案: const defaultFontFamily = { ...Platform.select({ android: { fontFamily: "" }, }), } const oldRender = Text.render Text.render = function (...args)

随机推荐