[英]React Native Count up Timer inside FlatList
嗨,我是 React Native 的新手,现在我正在尝试在每个 Flat List 行中创建计数计时器。 基于数据时间戳的计算与当前日期进行比较。 我的倒计时间隔适用于每一行,但现在的问题是性能。 在 Android 中有时会导致 ANR(应用程序无响应)。
有什么建议可以改进此代码吗? 真的很感激任何帮助。 谢谢你。
import React, { useState, useEffect } from 'react'
import { View, Text, ActivityIndicator, Modal, FlatList } from 'react-native'
import Style from '../../../../constants/Style'
import AsyncStorage from '@react-native-community/async-storage'
import { API, Auth } from 'aws-amplify'
import AWSMQTTConnection from '../../../../common/AWSMQTTConnection'
import AsyncStorageConstants from '../../../../constants/AsyncStorageConstants'
var isLeaving = false
function EquipmentElement({ id, name, number, status, time, maintenanceCode }) {
const [hours, setHours] = useState('00')
const [minutes, setMinutes] = useState('00')
const [seconds, setSeconds] = useState('00')
var count = setInterval(() => {
var now = new Date().getTime()
var distance = now - time
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60))
var seconds = Math.floor((distance % (1000 * 60)) / 1000)
var isHourLessThanTen = hours < 10
var isMinuteLessThanTen = minutes < 10
var isSecondLessThanTen = seconds < 10
if (isHourLessThanTen) {
hours = '0' + hours
}
if (isMinuteLessThanTen) {
minutes = '0' + minutes
}
if (isSecondLessThanTen) {
seconds = '0' + seconds
}
if ((status == 'Available' || status == undefined) || maintenanceCode == 1) {
clearInterval(count)
} else {
if (isLeaving) {
clearInterval(count)
} else {
setHours(hours)
setMinutes(minutes)
setSeconds(seconds)
}
}
}, 1000)
const setDurationValue = () => {
if (maintenanceCode == 1) {
<Text style={Style.value}>00:00:00</Text>
} else {
if (time != 0 || time != '' || time == undefined) {
return (<Text style={Style.value}>{hours}:{minutes}:{seconds}</Text>)
} else {
return (<Text style={Style.value}>00:00:00</Text>)
}
}
}
return (
<View style={Style.smartElementContainer}>
{setDurationValue()}
</View>
)
}
function Equipment() {
const [equipmentData, setEquipmentData] = useState([])
useEffect(() => {
isLeaving = false
getEquipmentList(false)
return function cleanup() {
console.log('unmounting...')
isLeaving = true
setEquipmentData([])
}
}, [])
const getEquipmentList = async (isMQTT) => {
try {
let propertyId = await AsyncStorage.getItem(AsyncStorageConstants.StorageConstants.CURRENT_PROPERTY_ID)
let apiName = 'DemoAsiaIoT'
let path = '/scdevice'
let request = {
headers: { Authorization: `Bearer ${(await Auth.currentSession()).getIdToken().getJwtToken()}` },
response: true,
queryStringParameters: {
propertyId: propertyId,
applicationId: 5
}
}
await API.get(apiName, path, request).then(response => {
var data = response.data.resultData
var devices = []
for (var i = 0; i < data.length; i++) {
var device = data[i]
devices.push({ id: device.deviceEUI, name: device.deviceName, number: '01', status: device.status, time: device.timestampStart, maintenanceCode: device.manualOverRide })
}
setEquipmentData(devices)
}).catch(error => {
console.log('Error from request - ', error.response)
})
} catch (err) {
console.log('error:', err)
}
}
return (
<View style={{ flex: 1 }}>
<FlatList
style={{
width: '100%',
marginTop: 10,
}}
showsVerticalScrollIndicator={false}
vertical={true}
data={equipmentData}
renderItem={({ item }) => <EquipmentElement id={item.id} name={item.name} number={item.number} status={item.status} time={item.time} maintenanceCode={item.maintenanceCode} />}
keyExtractor={item => item.id} />
</View>
)
}
export default Equipment
很少有关于如何优化代码的提示。
hours
、 minutes
和seconds
来在您的 FlatList 项目中显示您的时间。 这些是从Date.now()
派生的。 你可以查看下面的代码来理解这个概念。 只需在组件范围之外创建一个辅助函数,即可返回要显示的格式化时间。 如果你这样做,你的大部分表现都可以得到解决。function calculateTimeLeft() {
const year = new Date().getFullYear();
const difference = +new Date(`${year}-10-1`) - +new Date();
let timeLeft = {};
if (difference > 0) {
timeLeft = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60)
};
}
return timeLeft;
}
function FlatListItem() {
const [timeLeft, setTimeLeft] = React.useState(calculateTimeLeft());
React.useEffect(() => {
const id = setTimeout(() => {
setTimeLeft(calculateTimeLeft());
}, 1000);
return () => {
clearTimeout(id);
};
});
const timerComponents = Object.keys(timeLeft).map(interval => {
if (!timeLeft[interval]) {
return;
}
return (
<span>
{timeLeft[interval]} {interval}{" "}
</span>
);
});
我不知道为什么要在您的组件中设置isLeaving
。 去掉它。 这是没有用的。 在useEffect
的 return 语句上clearTimeout
。
使用StyleSheet.create
。 创建一个函数keyExtractor
并将其放置在您的组件之外。 并将项目作为道具传递。
// outside the scope of your component
function keyExtractor(item) {
return item.id;
}
<FlatList
style={styles.flatlist} // place your styles in `StyleSheet.create`
showsVerticalScrollIndicator={false}
vertical={true}
data={equipmentData}
renderItem={EquipmentElement} // pass the item as a prop
keyExtractor={keyExtractor}
/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.