简体   繁体   中英

React Native Flatlist don't rerender on PureComponent

Below is my Flatlist code. It is working fine but it was a bit laggy. So i search a bit on internet and found out that changing Component to PureComponent boost the flatlist performance. So i changed that but after that my iconType dont works. It doesn't changes that checkbox when user touches the list item. Is PureComponent don't rerender on touch?

<FlatList
  style={{flex:1}}
  data={finalData}
  showsVerticalScrollIndicator={false}
  renderItem={({item})=>{
    var iconType = (this.state.selectedItems.indexOf(item.name)>-1?"ios-checkmark-circle":"ios-checkmark-circle-outline");
    return(
      <TouchableOpacity
        onPress={
          ()=>{
            var selectedItems = this.state.selectedItems;
            var selectedItemsData = this.state.selectedItemsData;
            if(selectedItems.indexOf(item.name)>-1){
              const index = selectedItems.indexOf(item.name);
              selectedItems.splice(index, 1);
              selectedItemsData.splice(index,1);
            }else{
              selectedItems.push(item.name);
              selectedItemsData.push({name:item.name,id:item.id});
            }

            this.setState({selectedItems});
            this.setState({selectedItemsData});
          }}>
        <View style={{padding:20,flexDirection:'row',alignItems:'flex-start'}}>
          <Icon name={iconType} color="#45AA6F" size={25} />
          <Text style={{marginLeft:10,paddingTop:4,color:'#9B9B9B',fontWeight:'500'}}>{item.name}</Text>
        </View>
        <Dash style={{height:1}} dashColor="#45AA6F"/>
      </TouchableOpacity>)}
  }
/>

PureComponent will prevent wasteful re-renders unless the actual id change, By passing extraData={this.state} to FlatList we make sure FlatList itself will re-render when the state.selected changes. Just add the extraData prop to your flatlist component. Source: Official Document Flatlist

  /* Sample FlatList Example */ import React, { PureComponent} from 'react'; import { FlatList, StyleSheet, Switch, Text, View, } from 'react-native'; export default class FlatListView extends PureComponent { constructor(props: Object) { super(props); this.state = { words: [ { key: 1, text: 'Notification', toggle:false}, { key: 2, text: 'Wifi', toggle:false}, { key: 3, text: 'Bluetooth', toggle:false} ] } }; render() { return( <FlatList data={this.state.words} extraData={this.state} renderItem={({item, index}) => <View style={styles.wordsContainer}> <Text>{item.text}</Text> <Switch style={styles.pilgrimsWordSwitch} onValueChange={(toggleValue) => { /* * Cloning the words array to temp, So that the reference to this.state.words array will change. * Means this.state.words === temp will give false value. */ let temp = this.state.words.slice(0); temp[index].toggle = toggleValue; this.setState({words: temp}); }} value={ item.toggle } /> </View> } /> ) } } const styles = StyleSheet.create({ wordsContainer: { alignItems:'center', backgroundColor:'green', flexDirection:'row', height:100, justifyContent:'center', padding:20, }, pilgrimsWordSwitch: { flex:1, justifyContent:'flex-end' } }); 

dont mutate the array, that can cause component not re-render:

selectedItems.splice(index, 1); replace with non-mutating process.

you can probably use Array.filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter or

Array.map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

here you can compare non-mutating vs mutating methods: https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM