如何解决在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
。去掉它。这是没有用的。clearTimeout
useEffect
的退货声明中。 -
使用
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}
/>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。