網站首頁 編程語言 正文
正文
在 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
)
}
示例
這里有一個示例,供你參考。
原文鏈接:https://juejin.cn/post/7129319913331621902
相關推薦
- 2022-08-15 數據結構之有頭鏈表的實現
- 2022-05-23 C語言也有封裝,繼承和多態你知道嗎_C 語言
- 2022-08-22 python單元測試框架pytest介紹_python
- 2022-04-27 Django與DRF結合的全局異常處理方案詳解_python
- 2022-11-02 使用ggsignif優雅添加顯著性標記詳解_R語言
- 2023-05-17 一文速學Python+Pyecharts繪制樹形圖_python
- 2022-08-01 iOS?UITextView?實現類似微博的話題、提及用戶效果_IOS
- 2023-05-05 Golang實現簡易的命令行功能_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支