当前位置: 首页 > news >正文

写一个关于RN的分秒毫秒组件(组件状态由同一个父组件控制)

介绍一下,就一个界面会一直跑时间,项目有个需求需要用到毫秒级计时器,那我肯定想到用组件了塞,但是组件的状态和组件的数据都是不互通的都是独立的,因此我写了下面这个组件,组件的状态会由父组件控制切记,必须是同一个父组件,因为状态是父组件控制的,如果是多个页面多个父组件的话可以不用看,一键控制所有的组件的开启或者暂停,也可以控制所有组件是否重新启动重新计时,当前也考虑到了如果组件不是同时出现这个数据怎么保持一致的这个方案,组件代码如下

import React, { useState, useEffect, useRef } from 'react'
import { Text, View, Button, StyleSheet } from 'react-native'const Timer = ({ isRunning, elapsedTime, onStart, onStop, firstElapsedTime }) => {const startTimeRef = useRef(null)const animationIdRef = useRef(null)const previousTimeRef = useRef(0)const startTimer = () => {startTimeRef.current = Date.now() - elapsedTimeanimationIdRef.current = requestAnimationFrame(updateTimer)}const stopTimer = () => {cancelAnimationFrame(animationIdRef.current)}const updateTimer = () => {const currentTime = Date.now()const elapsedTime = currentTime - startTimeRef.currentpreviousTimeRef.current = elapsedTimeonStart(elapsedTime)animationIdRef.current = requestAnimationFrame(updateTimer)}useEffect(() => {if (isRunning) {startTimer()} else {stopTimer()}return () => {stopTimer()}}, [isRunning])const handleControl = () => {if (isRunning) {onStop()} else {startTimer()}}const formatTime = (milliseconds) => {const minutes = Math.floor(milliseconds / (60 * 1000))const seconds = Math.floor((milliseconds % (60 * 1000)) / 1000)const millisecondsFraction = Math.floor((milliseconds % 1000) / 10)return ((minutes < 10 ? '0' : '') + minutes + ':' +(seconds < 10 ? '0' : '') + seconds + ':' +(millisecondsFraction < 10 ? '0' : '') + millisecondsFraction)}return (<View><Text>{formatTime(firstElapsedTime)}</Text></View>)
}const ParentComponent = () => {const [timers, setTimers] = useState([{ id: 1, isRunning: false, elapsedTime: 0 },{ id: 2, isRunning: false, elapsedTime: 0 },{ id: 3, isRunning: false, elapsedTime: 0 },])const [nextId, setNextId] = useState(4)const handleStartAll = () => {setTimers(timers.map(timer => ({ ...timer, isRunning: true })))}const handlePauseAll = () => {setTimers(timers.map(timer => ({ ...timer, isRunning: false })))}const handleContinueAll = () => {setTimers(timers.map(timer => ({ ...timer, isRunning: true })))}const handleRestartAll = () => {handlePauseAll()setTimeout(() => {setTimers(timers.map(timer => ({ ...timer, isRunning: true, elapsedTime: timers[0].elapsedTime })))}, 100)}const handleAddTimer = () => {const firstTimerElapsedTime = timers[0].elapsedTime // 获取第一个计时器组件的时间const newTimer = { id: nextId, isRunning: false, elapsedTime: firstTimerElapsedTime }setNextId(nextId + 1)setTimers([...timers, newTimer])}return (<View style={styles.container}><View style={styles.timerContainer}>{timers.map(timer => (<Timerkey={timer.id}isRunning={timer.isRunning}elapsedTime={timer.elapsedTime}onStart={elapsedTime => {const newTimers = [...timers]const index = newTimers.findIndex(t => t.id === timer.id)newTimers[index].elapsedTime = elapsedTimesetTimers(newTimers)}}onStop={() => {const newTimers = [...timers]const index = newTimers.findIndex(t => t.id === timer.id)newTimers[index].isRunning = falsesetTimers(newTimers)}}firstElapsedTime={timers[0].elapsedTime} // 传递第一个计时器的elapsedTime给Timer组件/>))}</View><View style={styles.buttonContainer}><Button title={timers.some(timer => timer.isRunning) ? '全部暂停' : '全部开始'} onPress={timers.some(timer => timer.isRunning) ? handlePauseAll : handleStartAll} /><Button title="继续" onPress={handleContinueAll} /><Button title="重新启动" onPress={handleRestartAll} /><Button title="添加新组件(需要先暂停才行,时间最初为00:00:00,点击开始后时间以第一个组件时间为准)" onPress={handleAddTimer} /></View></View>)
}const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},timerContainer: {marginBottom: 20,},buttonContainer: {flexDirection: 'column',justifyContent: 'space-around',marginTop: 20,},
})export default ParentComponent

上面的组件说明下:(时间会有差别,但是差别不大,基本在几毫秒之内,为了保持数据的一致性,我将都参照第一个组件的时间为准,点击暂停时,所有组件的时间都跟第一个组件保持一致)
点击开始:所有组件开始计时
点击暂停:所有组件全部暂停
点击重启:计时从0开始,重新计时
点击新增组件:需要先暂停才行,因为页面一直在渲染添加不上,我没解决掉,有大佬能解决了更好,还有就是时间以第一个组件显示的时间为准,包括暂停也都是(为了保证所有组件计时的时间的同步)

PS:上面的那个组件展示没必要用循环奥,直接按照下面写也行【如果需要用循环写,也可用循环】

<Timerkey={timers[0].id}isRunning={timers[0].isRunning}elapsedTime={timers[0].elapsedTime}onStart={elapsedTime => {const newTimers = [...timers]const index = newTimers.findIndex(t => t.id === timers[0].id)newTimers[index].elapsedTime = elapsedTimesetTimers(newTimers)}}onStop={() => {const newTimers = [...timers]const index = newTimers.findIndex(t => t.id === timers[0].id)newTimers[index].isRunning = falsesetTimers(newTimers)}}firstElapsedTime={timers[0].elapsedTime} // 传递第一个计时器的elapsedTime给Timer组件/>

上面代码在需要用到组件的地方直接用就行,相当于每个组件都用第一个的状态,或者每个都用自己的状态其实效果是一样的,这种是对于不需要循环在某一个地方使用的情况,就算是循环直接循环三个这样的也行,总之就是这样写也可以,用循环写也可以,这个各位自己定

相关文章:

写一个关于RN的分秒毫秒组件(组件状态由同一个父组件控制)

介绍一下,就一个界面会一直跑时间,项目有个需求需要用到毫秒级计时器,那我肯定想到用组件了塞,但是组件的状态和组件的数据都是不互通的都是独立的,因此我写了下面这个组件,组件的状态会由父组件控制切记&#xff0c;必须是同一个父组件&#xff0c;因为状态是父组件控制的&…...

javascript中字符串处理,常用的方法汇总

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;前端泛海 景天的主页&#xff1a;景天科技苑 文章目录 字符串对象的的相关方法1.获取字符串长度 length2.通过索引获取元素 …...

STM32CubeMX学习笔记14 ---SPI总线

1. 简介 1.1 SPI总线介绍 SPI 是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola(摩托罗拉)首先在其MC68HCXX系列处理器上定义的。 SPI&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在…...

Gson(List<Object>转String 、String转List<Object>)

要在Java项目中使用Gson库&#xff0c;你需要添加相应的依赖项。以下是在Maven项目的pom.xml文件中添加Gson依赖的示例&#xff1a; <dependencies><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId>&l…...

uniapp路由跳转的方式

1. uniapp路由跳转的方式 1.1. uni.navigateTo保留当前页面&#xff0c;跳转到应用内的某个页面&#xff0c;使用uni.navigateBack可以返回到原页面。 uni.navigateTo({url:./index/index });注意&#xff1a; &#xff08;1&#xff09;页面跳转路径有层级限制&#xff0c;不…...

使用Python模拟绘制自由落体运动过程中的抛物线

目录 一、引言 二、自由落体运动的基本原理 三、使用Python模拟自由落体运动 四、扩展功能&#xff1a;添加速度曲线和动画效果 五、总结与展望 一、引言 自由落体运动是物理学中最基础的运动形式之一&#xff0c;它描述了一个物体在仅受重力作用下的运动轨迹。在这个…...

批量爬取网站图片脚本

不分文件夹 import requests from bs4 import BeautifulSoup import os from concurrent.futures import ThreadPoolExecutordef download_image(img_url):# 检查图片后缀是否为.jpg或.jpegif img_url.lower().endswith((.jpg, .jpeg)):try:img_response requests.get(img_ur…...

scrapy 爬虫:多线程爬取去微博热搜排行榜数据信息,进入详情页面拿取第一条微博信息,保存到本地text文件、保存到excel

如果想要保存到excel中可以看我的这个爬虫 使用Scrapy 框架开启多进程爬取贝壳网数据保存到excel文件中&#xff0c;包括分页数据、详情页数据&#xff0c;新手保护期快来看&#xff01;&#xff01;仅供学习参考&#xff0c;别乱搞_爬取贝壳成交数据c端用户登录-CSDN博客 最终…...

网络、UDP编程

1.网络协议模型: OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#xff09; 网络层 …...

VSCode安装与使用

1、下载地址&#xff1a;Documentation for Visual Studio Code 在 VS Code 中使用 Python - 知乎 (zhihu.com) 自动补全和智能感知检测、调试和单元测试在Python环境(包括虚拟环境和 conda 环境)之间轻松切换 在 VS Code 中安装插件非常的简单&#xff0c;只需要打开 VS Code…...

进程和线程的区别与联系

进程和线程是计算机系统中两个重要的概念&#xff0c;它们在操作系统中扮演着不同的角色&#xff0c;并有着不同的特点和用途。以下是详细信息&#xff1a; 进程。进程是操作系统中资源分配的基本单位&#xff0c;它包括程序、数据和进程控制块。每个进程都有自己的地址空间&a…...

6、Redis-KV设计、全局命令和安全性

目录 一、value设计 二、Key设计 三、全局命令——针对所有key 四、安全性 一、value设计 ①是否需要排序&#xff1f;需要&#xff1a;Zset ②需要缓存的数据是单个值还是多个值&#xff1f; 单个值&#xff1a;简单值---String&#xff1b;对象值---Hash多个值&#x…...

python之海龟绘图

海龟绘图&#xff08;turtle&#xff09;是一个Python内置的绘图库&#xff0c;也被称为“Turtle Graphics”或简称“Turtles”。它采用了一种有趣的绘图方式&#xff0c;模拟一只小海龟在屏幕上爬行&#xff0c;而小海龟爬行的路径就形成了绘制的图形。这种绘图方式最初源自20…...

Java实战:Spring Boot 实现异步记录复杂日志

日志记录是软件开发中非常重要的一环&#xff0c;它可以帮助我们快速定位问题、监控程序运行状态等。在 Spring Boot 应用中&#xff0c;异步记录日志是一种常见的需求。本文将详细介绍如何在 Spring Boot 中实现异步记录复杂日志&#xff0c;包括异步日志的基本原理、实现方式…...

“色狼”用英语怎么说?柯桥日常英语,成人英语口语学习

最近有粉丝问我"色狼"英文翻译是啥 首先声明不是"colour wolf"哈 关于“色狼”的英文表达有很多 快和C姐一起来看看吧&#xff01; 1.pervert 这个单词的意思是变态、色狼 是对性变态者最直观的描述 He is such a pervert&#xff01; I saw him lo…...

Docker前后端项目部署

目录 一、搭建项目部署的局域网 二、redis安装 三、MySQL安装 四、若依后端项目搭建 4.1 使用Dockerfile自定义镜像 五、若依前端项目搭建 一、介绍前后端项目 一张图带你看懂ruoyi的前后端项目部署 得出结论&#xff1a;需要4台服务器&#xff0c;都处于同一个局域网中…...

如何快速的搭建一个小程序

要快速搭建一个小程序&#xff0c;你可以按照以下步骤进行&#xff1a; 明确目标和需求&#xff1a;在开始搭建小程序之前&#xff0c;首先明确你的小程序的主要功能、目标用户以及希望实现的业务需求。这将帮助你更好地规划和设计小程序。选择小程序平台&#xff1a;根据你的…...

STM32自学☞AD多通道

涉及到的硬件有&#xff1a;光敏传感器&#xff0c;热敏传感器&#xff0c;红外对射传感器&#xff0c;电位器 通过adc将他们采集的模拟信号转换为数值 ad.c文件 #include "stm32f10x.h" #include "stm32f10x_adc.h" #include "ad.h" #inc…...

微服务之商城系统

一、商城系统建立之前的一些配置 1、nacos Nacos是一个功能丰富的开源平台&#xff0c;用于配置管理、服务发现和注册、健康检查等&#xff0c;帮助构建和管理分布式系统。 在linux上安装nacos容器的命令&#xff1a; docker run --name nacos-standalone -e MODEstandalone …...

安卓玩机工具推荐----高通芯片9008端口读写分区 备份分区 恢复分区 制作线刷包 工具操作解析

上期解析了下adb端口备份分区的有关操作 安卓玩机工具推荐----ADB状态读写分区 备份分区 恢复分区 查看分区号 工具操作解析 在以往的博文中对于高通芯片机型的分区读写已经分享了很多。相关类似博文 安卓备份分区----手动查询安卓系统分区信息 导出系统分区的一些基本操作 …...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

小木的算法日记-多叉树的递归/层序遍历

&#x1f332; 从二叉树到森林&#xff1a;一文彻底搞懂多叉树遍历的艺术 &#x1f680; 引言 你好&#xff0c;未来的算法大神&#xff01; 在数据结构的世界里&#xff0c;“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的&#xff0c;它…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...