React Native Flatlist不会在PureComponent上重新渲染

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Native Flatlist不会在PureComponent上重新渲染相关的知识,希望对你有一定的参考价值。

下面是我的Flatlist代码。它工作正常,但有点滞后。所以我在互联网上搜索了一下,发现将Component更改为PureComponent会提升平板列表的性能。所以我改变了,但之后我的iconType不起作用。当用户触摸列表项时,它不会更改该复选框。 PureComponent不会在触摸时重新渲染吗?

<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将防止浪费的重新渲染,除非实际的id更改,通过将extraData = {this.state}传递给FlatList,我们确保FlatList本身将在state.selected更改时重新呈现。只需将extraData prop添加到您的flatlist组件即可。资料来源: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'
  }
});
另一答案

不要改变数组,这可能导致组件不重新渲染:

selectedItems.splice(index, 1);取代了非变异过程。

你可以使用Array.filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

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

在这里你可以比较非变异和变异的方法:https://lorenstewart.me/2017/01/22/javascript-array-methods-mutating-vs-non-mutating/

以上是关于React Native Flatlist不会在PureComponent上重新渲染的主要内容,如果未能解决你的问题,请参考以下文章

React Native FlatList 与其他组件不会滚动到最后

React Native FlatList 没有滚动到结束

react-native ScrollView 嵌套 FlatList滚动

React Native之FlatList组件(一)

在 React 中等效于来自 React Native 的 FlatList

React Native FlatList 嵌套在具有相同方向的 FlatList 中