【问题标题】:React Native Flatlist don't rerender on PureComponentReact Native Flatlist 不会在 PureComponent 上重新渲染
【发布时间】:2018-12-26 00:50:46
【问题描述】:

下面是我的 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>)}
  }
/>

【问题讨论】:

    标签: javascript reactjs react-native ecmascript-6


    【解决方案1】:

    PureComponent 将防止浪费的重新渲染,除非实际的 id 发生变化, 通过将 extraData={this.state} 传递给 FlatList,我们确保 FlatList 本身会在 state.selected 更改时重新渲染。只需将 extraData 道具添加到您的 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'
      }
    });

    【讨论】:

    • 因为您没有在 onpress 函数中更新数据 = {finalData}。所以它不会重新渲染,因为 props{finalData} 保持浅相等。
    • 如果我改回 PureComponent 然后它停止更改
    • 有任何在 Touch 事件中使用 PureComponent 的工作示例
    • 您正在使用组件进行扩展。我的脚本在 Component 上工作得很好,但是当我用 PureComponent 扩展它时它停止工作
    • 将组件更改为 PureComponent
    【解决方案2】:

    不要改变数组,这会导致组件无法重新渲染:

    selectedItems.splice(index, 1); 替换为非变异进程。

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

    Array.maphttps://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/

    【讨论】:

    • 我没有听从你的回答,我的问题完全不同。我不是在触摸时推动或切片任何东西,我只是在触摸时改变项目的状态
    猜你喜欢
    • 2018-12-27
    • 1970-01-01
    • 2018-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多