【问题标题】:React Native ListView TextInput locks up from performance optimization renderingReact Native ListView TextInput 锁定性能优化渲染
【发布时间】:2017-06-21 03:48:02
【问题描述】:

我正在尝试为列表视图的每一行中包含的每个文本输入设置一个状态值。

问题在于,React Native 的 ListView 组件有一堆优化技术,比如删除屏幕外的行。这导致了一个问题,因为 TextInputs 正在锁定它们的 value 属性,编辑它们将不再反映更改并且状态值被锁定或其他东西。我附上了一段视频来展示这种行为。

https://www.youtube.com/watch?v=fq7ITtzRvg4&feature=youtu.be

    _renderRow(value){
    let tempWidth = window.width / 2.13
    if(value.data.length == 1){
        tempWidth = window.width*0.970
    }
    var Images =  value.data.map((b,i) => {
        let source = { uri: BUCKETIMAGES+'/'+b.image_filename}
        return (
            <TouchableOpacity key={i} style={styles.cardImage}>
                {b.profile_picture &&
                <View style={{zIndex: 4, width:31,height:31,borderWidth:1,borderColor:"#ccc",borderRadius:20, position: "absolute", right: -6, top: -6}}>
                    <CacheableImage style={{width:30,height:30,borderWidth:3,borderColor:"white",borderRadius:15,position: "absolute", right: 0, top: 0}} source={{uri: BUCKETIMAGES+'/'+b.profile_picture}}/>
                </View>
                }
                <CacheableImage source={source} style={{height: 150, width: tempWidth}}/>
            </TouchableOpacity>
        )
    });
    return(
            <View key={value.id} style={styles.statusContainer}>
                 <View style={[styles.statusHeader,{height: 50, alignItems: "center"}]}>
                    <View style={{flex:0.85}}>
                            <View style={{flexDirection: "row"}}> 
                                <Text style={{color: "#666666", fontWeight: "bold", fontSize: 18, paddingLeft: 20}}>Team {value.type}</Text>
                            </View>
                            <Text style={{color: "grey", fontSize: 15, paddingLeft: 20, paddingRight: 20}}>{value.date}</Text>
                    </View>
                    <View style={{flex:0.15,height: 20, justifyContent: "center",width: 30}}>
                            <Icon name="ios-more" type="ionicon" size={40} color="#a9a9a9" />
                    </View>
                </View>
                <View style={{flexDirection: "row", flexWrap: "wrap"}}>
                    { Images }
                </View>
                <View style={{zIndex: 10}}>

                </View>
                <View style={[styles.commentHeader,{height: 30,flex:0.8, zIndex: 5}]}>
                    <View style={{height: 30, width: 40}}>
                            <Icon name="ios-chatboxes-outline" type="ionicon" size={30} color="grey" />
                    </View>
                    <View style={{flex:0.9}}>
                            <TextInput
                                style={styles.commentInput}
                                placeholder="Say something..."
                                placeholderTextColor="gray"
                                underlineColorAndroid="transparent"
                                multiline={true}
                                blurOnSubmit={true}
                                value={this.state['comment'+value.id]}
                                onChangeText={(commentInput) => {this.setState({["comment"+value.id]: commentInput})}}
                            />
                    </View>
                    <View style={{justifyContent: "center", marginRight: 20}}>
                        <TouchableOpacity onPress={() => {this.setState({commentID: value.id}, this.addComment)}}>
                            <Icon name="md-send" type="ionicon" size={25} color="#CCC" />
                        </TouchableOpacity>
                    </View>
                </View>    
            </View>
    )
}

render() {
    return(
        <View style={styles.container}>
            {Platform.OS === "ios" &&
            <View style={styles.statusBar}></View>
            }
            {this.state.loading &&
            <ActivityIndicator
                animating={true}
                color="#E91E63"
                size="large"
                style={{marginTop: 80}}
            />
            }
            {!this.state.loading &&
            <ListView
                    dataSource = {this.state.dataSource}
                    renderRow  = {this._renderRow.bind(this)}
                    initialListSize={10}
                    enableEmptySections={true}
            />}
        </View>
    )
}

【问题讨论】:

标签: javascript android reactjs listview react-native


【解决方案1】:

我建议创建一个组件来呈现每一行,以便每个项目都可以保持自己的状态。我已经使用 ListView 对 500 多行进行了类似的操作,并且效果很好。

【讨论】:

  • 非常感谢!您的赏金将在 6 小时内发放
【解决方案2】:

使用 react-native 0.45.1,我很快用 1000 行制作了这个模型,并且 TextInput 工作正常。它不像您的演示那样锁定....即使您一直向下滚动到最后并备份,TextInput 状态是正确的,并且仍然可以编辑。

我建议从这个模型开始,然后构建你的实现,看看它在哪里中断。

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  ListView,
  TextInput
} from 'react-native';


const mocks = []
for (var i = 0; i < 1000; i++) {
  mocks.push({
    id:i,
    text: `I am row ${i}`
  })
}


export default class test extends Component {

  constructor(){
    super()
    this.ds = new ListView.DataSource({ rowHasChanged: (r1,r2) => r1 !== r2 })
    this.state = {
      ds: this.ds.cloneWithRows(mocks),
    }
  }

  renderRow = (value) => {
    return(
      <View style={ styles.rowContainer }>
        <Text>{ value.text }</Text>
        <TextInput
          style={ styles.textInput }
          value={ this.state[`comment${value.id}`] }
          onChangeText={ (text) => this.setState({ [`comment${value.id}`]:text }) }
        />
      </View>
    )
  }

  render() {
    return (
      <View style={styles.container}> 
        <ListView
          dataSource={ this.state.ds }
          renderRow={ this.renderRow }
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#F5FCFF',
  },
  rowContainer:{
    padding:10,
    marginBottom:10,
    backgroundColor: 'rgb(222,222,222)'
  },
  textInput:{
    backgroundColor: 'white',
    height: 50,
  }
});

AppRegistry.registerComponent('test', () => test);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    相关资源
    最近更新 更多