Javascript 有没有办法在平面列表中使用可变数组?
我正在尝试做一个玩具秒表应用程序,以学习如何反应 我做了一圈制,但当圈数超过15圈时,速度太慢了。我认为性能差的地方是Javascript 有没有办法在平面列表中使用可变数组?,javascript,reactjs,react-native,react-native-flatlist,Javascript,Reactjs,React Native,React Native Flatlist,我正在尝试做一个玩具秒表应用程序,以学习如何反应 我做了一圈制,但当圈数超过15圈时,速度太慢了。我认为性能差的地方是laps:this.state.laps.concat([d-this.state.lapTimerStart])部分,因为.concat在每次按下Lap按钮时都会生成一个新对象 我听说.push比.concat快得多 所以我试着使用.push,但是因为.push改变了数组,而FlatList是一个纯组件,所以只有当道具发生变化时才会重新渲染 我找到了一种方法,但这和做.conc
laps:this.state.laps.concat([d-this.state.lapTimerStart])
部分,因为.concat在每次按下Lap
按钮时都会生成一个新对象
我听说.push
比.concat
快得多
所以我试着使用.push
,但是因为.push
改变了数组,而FlatList
是一个纯组件,所以只有当道具发生变化时才会重新渲染
我找到了一种方法,但这和做.concat
一样,因为基本上是这样
let lapArr = this.state.laps;
Array.prototype.push.apply(lapArr, [d - this.state.lapTimerStart]);
this.setState({
laps: lapArr,
})
完整的代码是
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableHighlight,
FlatList,
} from 'react-native';
import {useTheme} from 'react-native-paper';
import TimeFormatter from 'minutes-seconds-milliseconds';
class Stopwatch extends Component {
constructor(props) {
super(props);
this.state = {
laps: [],
isRunning: false,
mainTimer: null,
lapTimer: null,
mainTimerStart: null,
lapTimerStart: null,
};
}
handleLapReset() {
let {isRunning, mainTimerStart, lapTimer} = this.state;
if (mainTimerStart) {
if (isRunning) {
const d = new Date();
this.setState({
lapTimerStart: d,
lapTimer: d - this.state.lapTimerStart + lapTimer,
laps: this.state.laps.concat([d - this.state.lapTimerStart]),
});
return;
}
this.state.laps = [];
this.setState({
mainTimerStart: null,
lapTimerStart: null,
mainTimer: 0,
lapTimer: 0,
});
}
}
handleStartStop() {
let {isRunning, mainTimer, lapTimer} = this.state;
if (isRunning) {
clearInterval(this.interval);
this.setState({
isRunning: false,
});
return;
}
const d = new Date();
this.setState({
mainTimerStart: d,
lapTimerStart: d,
isRunning: true,
});
this.interval = setInterval(() => {
const t = new Date();
this.setState({
mainTimer: t - this.state.mainTimerStart + mainTimer,
lapTimer: t - this.state.lapTimerStart + lapTimer,
});
}, 10);
}
_renderTimers() {
const {theme} = this.props;
return (
<View
style={[
styles.timerWrapper,
{backgroundColor: theme.colors.background},
]}>
<View style={styles.timerWrapperInner}>
<Text style={[styles.lapTimer, {color: theme.colors.text}]}>
{TimeFormatter(this.state.lapTimer)}
</Text>
<Text style={[styles.mainTimer, {color: theme.colors.text}]}>
{TimeFormatter(this.state.mainTimer)}
</Text>
</View>
</View>
);
}
_renderButtons() {
const {theme} = this.props;
return (
<View style={styles.buttonWrapper}>
<TouchableHighlight
underlayColor={theme.colors.disabled}
onPress={this.handleLapReset.bind(this)}
style={[styles.button, {backgroundColor: theme.colors.background}]}>
<Text style={[styles.lapResetBtn, {color: theme.colors.text}]}>
{this.state.mainTimerStart && !this.state.isRunning
? 'Reset'
: 'Lap'}
</Text>
</TouchableHighlight>
<TouchableHighlight
underlayColor={theme.colors.disabled}
onPress={this.handleStartStop.bind(this)}
style={[styles.button, {backgroundColor: theme.colors.background}]}>
<Text
style={[styles.startBtn, this.state.isRunning && styles.stopBtn]}>
{this.state.isRunning ? 'Stop' : 'Start'}
</Text>
</TouchableHighlight>
</View>
);
}
_renderLaps() {
return (
<View style={styles.lapsWrapper}>
<FlatList
data={this.state.laps}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
/>
</View>
);
}
keyExtractor(item, index) {
return index.toString();
}
renderItem({item, index}) {
return (
<View style={styles.lapRow}>
<View style={styles.lapStyle}>
<View style={styles.lapBoxStyle} />
<Text style={styles.lapNumber}>{index + 1}</Text>
</View>
<View style={styles.lapStyle}>
<Text style={styles.lapTime}>{TimeFormatter(item)}</Text>
</View>
</View>
);
}
render() {
return (
<View style={styles.container}>
<View style={styles.top}>{this._renderTimers()}</View>
<View style={styles.middle}>{this._renderButtons()}</View>
<View style={styles.bottom}>{this._renderLaps()}</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {flex: 1},
timerWrapper: {
justifyContent: 'center',
flex: 1,
},
top: {
flex: 1,
},
middle: {
flex: 1,
backgroundColor: '#F0EFF5',
},
bottom: {
flex: 2,
},
mainTimer: {
fontSize: 50,
fontFamily: 'CircularStd-Medium',
alignSelf: 'center',
},
lapTimer: {
fontSize: 18,
fontFamily: 'CircularStd-Medium',
alignSelf: 'flex-end',
},
timerWrapperInner: {
alignSelf: 'center',
},
buttonWrapper: {
flexDirection: 'row',
justifyContent: 'space-around',
paddingTop: 15,
paddingBottom: 30,
},
button: {
height: 80,
width: 80,
borderRadius: 40,
backgroundColor: '#FFF',
justifyContent: 'center',
alignItems: 'center',
},
lapRow: {
flexDirection: 'row',
justifyContent: 'space-between',
height: 40,
paddingTop: 10,
},
lapNumber: {
flexDirection: 'row',
fontSize: 16,
fontFamily: 'CircularStd-Book',
color: '#777',
flex: 1,
},
lapTime: {
flexDirection: 'row',
color: '#000',
fontSize: 20,
fontFamily: 'CircularStd-Book',
flex: 1,
},
startBtn: {
color: '#0C0',
fontFamily: 'CircularStd-Book',
},
stopBtn: {
color: '#C00',
fontFamily: 'CircularStd-Book',
},
lapsWrapper: {
backgroundColor: '#ddd',
},
lapResetBtn: {
fontFamily: 'CircularStd-Book',
},
lapStyle: {
width: '40%',
flexDirection: 'row',
},
lapBoxStyle: {
flexDirection: 'row',
flex: 1,
},
});
export default function StopwatchScreen(props) {
const theme = useTheme();
return <Stopwatch {...props} theme={theme} />;
}
import React,{Component}来自'React';
进口{
看法
文本,
样式表,
触控高光,
平面列表,
}从“反应本机”;
从“react native paper”导入{useTheme};
从“分-秒-毫秒”导入TimeFormatter;
类秒表扩展组件{
建造师(道具){
超级(道具);
此.state={
圈数:[],
isRunning:false,
mainTimer:null,
lapTimer:null,
mainTimerStart:null,
lapTimerStart:null,
};
}
handleLapReset(){
让{isRunning,mainTimerStart,lapTimer}=this.state;
如果(mainTimerStart){
如果(正在运行){
const d=新日期();
这是我的国家({
lapTimerStart:d,
lapTimer:d-this.state.lapTimerStart+lapTimer,
laps:this.state.laps.concat([d-this.state.lapTimerStart]),
});
返回;
}
this.state.laps=[];
这是我的国家({
mainTimerStart:null,
lapTimerStart:null,
主计时器:0,
计时器:0,
});
}
}
扶手止动块(){
让{isRunning,mainTimer,lapTimer}=this.state;
如果(正在运行){
clearInterval(这个.interval);
这是我的国家({
isRunning:false,
});
返回;
}
const d=新日期();
这是我的国家({
mainTimerStart:d,
lapTimerStart:d,
isRunning:是的,
});
this.interval=setInterval(()=>{
const t=新日期();
这是我的国家({
mainTimer:t-this.state.mainTimerStart+mainTimer,
lapTimer:t-this.state.lapTimerStart+lapTimer,
});
}, 10);
}
_渲染器(){
const{theme}=this.props;
返回(
{TimeFormatter(this.state.lapTimer)}
{TimeFormatter(this.state.mainTimer)}
);
}
_renderButtons(){
const{theme}=this.props;
返回(
{this.state.mainTimerStart&!this.state.isRunning
“重置”
:'Lap'}
{this.state.isRunning?'Stop':'Start'}
);
}
_renderLaps(){
返回(
);
}
键提取器(项,索引){
返回索引.toString();
}
renderItem({item,index}){
返回(
{index+1}
{时间表(项目)}
);
}
render(){
返回(
{this.\u renderTimes()}
{this._renderButtons()}
{this.\u renderLaps()}
);
}
}
const styles=StyleSheet.create({
容器:{flex:1},
计时器记录器:{
为内容辩护:“中心”,
弹性:1,
},
顶部:{
弹性:1,
},
中间:{
弹性:1,
背景颜色:“#F0EFF5”,
},
底部:{
弹性:2,
},
主计时器:{
尺寸:50,
fontFamily:“圆形TD中等”,
对齐自我:“中心”,
},
膝上计时器:{
尺码:18,
fontFamily:“圆形TD中等”,
alignSelf:“柔性端”,
},
TimerRapperner:{
对齐自我:“中心”,
},
按钮振打器:{
flexDirection:'行',
为内容辩护:“周围的空间”,
paddingTop:15,
填充底部:30,
},
按钮:{
身高:80,
宽度:80,
边界半径:40,
背景颜色:“#FFF”,
为内容辩护:“中心”,
对齐项目:“居中”,
},
拉普罗:{
flexDirection:'行',
justifyContent:'之间的空间',
身高:40,
paddingTop:10,
},
编号:{
flexDirection:'行',
尺寸:16,
fontFamily:“通告书”,
颜色:'#777',
弹性:1,
},
洛杉矶时间:{
flexDirection:'行',
颜色:“#000”,
尺寸:20,
fontFamily:“通告书”,
弹性:1,
},
startBtn:{
颜色:'#0C0',
fontFamily:“通告书”,
},
stopBtn:{
颜色:'#C00',
fontFamily:“通告书”,
},
滑石机:{
背景颜色:“#ddd”,
},
lapResetBtn:{
fontFamily:“通告书”,
},
lapStyle:{
宽度:“40%”,
flexDirection:'行',
},
衣领款式:{
flexDirection:'行',
弹性:1,
},
});
导出默认功能秒表屏幕(道具){
const theme=useTheme();
返回;
}
- 我试着不使用箭头函数,很多是新的,但是没有多大帮助
FlatList
是一个纯组件,必须为呈现列表提供数据
属性的新引用。您应该使用concat
,但它创建了新对象
我认为主要的问题是renderItem
创建一个单独的PureComponent以避免重新呈现项目
class Item extends PureComponent {
const {item,index} = this.props;
return (
<View style={styles.lapRow}>
<View style={styles.lapStyle}>
<View style={styles.lapBoxStyle} />
<Text style={styles.lapNumber}>{index + 1}</Text>
</View>
<View style={styles.lapStyle}>
<Text style={styles.lapTime}>{TimeFormatter(item)}</Text>
</View>
</View>
);
}
类项扩展了PureComponent{
const{item,index}=this.props;
返回(
{index+1}
{时间表(项目)}
);
}
并在渲染项中使用
renderItem({item, index}) {
return (
<Item item={item} index={index} />
);
}
renderItem({item,index}){
返回(
);
}
我可以尝试复制,但有一些问题,1.-为什么要避免使用箭头函数?2.-您使用的是最新版本的