Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/408.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有办法在平面列表中使用可变数组?_Javascript_Reactjs_React Native_React Native Flatlist - Fatal编程技术网

Javascript 有没有办法在平面列表中使用可变数组?

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

我正在尝试做一个玩具秒表应用程序,以学习如何反应

我做了一圈制,但当圈数超过15圈时,速度太慢了。我认为性能差的地方是
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.-您使用的是最新版本的