Reactjs 对较大的列表进行本机分区列表优化

Reactjs 对较大的列表进行本机分区列表优化,reactjs,react-native,react-native-flatlist,Reactjs,React Native,React Native Flatlist,我有一个平面列表,最多可以有1000个项目。我已经尝试了所有的优化和现在顺利的决赛,但第一次渲染速度慢,渲染项目慢。基本上,我显示的是手机用户的联系人列表。这是我尝试过的代码 import React, { useState, useEffect, useRef, useMemo } from 'react'; import { SafeAreaView,Dimensions, SectionList, TextInput, FlatList,ActivityIndicator,

我有一个平面列表,最多可以有1000个项目。我已经尝试了所有的优化和现在顺利的决赛,但第一次渲染速度慢,渲染项目慢。基本上,我显示的是手机用户的联系人列表。这是我尝试过的代码

    import React, { useState, useEffect, useRef, useMemo } from 'react';
    import { SafeAreaView,Dimensions, SectionList, TextInput, FlatList,ActivityIndicator, Animated, StyleSheet, View, Text, PermissionsAndroid, StatusBar, NativeModules, TouchableOpacity} from 'react-native';
    const { MyCustomWindowManager } = NativeModules;
    import CallDetectorManager from 'react-native-call-detection'
    import Contacts from 'react-native-contacts';
    import FontAwesome  from 'react-native-vector-icons/FontAwesome';
    import EvilIcon from 'react-native-vector-icons/EvilIcons'
    import Entypo from 'react-native-vector-icons/Entypo'
    import Icon from 'react-native-vector-icons/Ionicons'

    const RenderItem = ({item}) => {
      if(item.phoneNumbers.length !== 0){
        return useMemo(() => {
        return (
            item.phoneNumbers.map(phone => (
            <TouchableOpacity key={phone}  style={styles.single_contact_style}>
              <EvilIcon name='user' size={40} color='#fff' style={{alignSelf:"center"}}/> 
              <View style={styles.name_number_view}>
                <Text style={[styles.text, {fontWeight:"bold"}]}>{item.name}</Text>
                <Text style={styles.text}>{phone}</Text>
              </View>        
          </TouchableOpacity>
        ))
        )
      }, []);
    }else{ return null}
    }

    const App = () => {
      const [contacts,setContacts] = useState([])
      const [searchdata,setSearchData] = useState([])
      const [loading, setLoading] = useState(true)
      const [search_text, setSearch_text] = useState("")
      const [permission , setPermission] = useState(false)
      useEffect(() => {
        PermissionsAndroid.requestMultiple([
          PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
          PermissionsAndroid.PERMISSIONS.READ_CONTACTS
        ]).then((result) =>{
          setPermission(result['android.permission.READ_CONTACTS']);
        
        }).catch((err) => {
          console.log(err)
        })
      },[]);

      
      useEffect(() =>{
        PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_CONTACTS).then((res) =>{
          if(res){
            Contacts.getAll().then(contacts1 => {
              let items = []
              contacts1.forEach((item,index) =>{
                items.push({
                  key:index,
                  name:item.displayName,
                  phoneNumbers:[...new Set(item.phoneNumbers.map(x => x.number.replace(/-|\s/g,"")))]
                })
              })
              setContacts(items)
              getData();
            })
          }else{
              alert("Please Enable Permission");
          }
        })
      
      
      },[contacts])
      
      const getData = () => {
      
        let contactArr = [];
        let aCode  = "A".charCodeAt(0); 
          for(let  i = 0 ; i<26 ;i++){
            let currChar  = String.fromCharCode(aCode+i);
            let obj ={
                title:currChar
            }
      

        let currContacts  = contacts.filter(item => {
            return item.name[0].toUpperCase() === currChar;
        });

        if(currContacts.length > 0){
            currContacts.sort((a,b) => a.name.localeCompare(b.name))
            obj.data = currContacts;
            contactArr.push(obj);
        }
      }
      setSearchData(contactArr)
      setLoading(false);
      }

      const renderMessage = () => {
        return (
            <View style={{flex:1, marginTop:'20%', justifyContent:"center", alignItems:"center"}}>
                <Icon name="md-alert-circle-outline" color="red" size={50} />
                <Text style={{color:'white',fontSize:20}}>
                    No Contact
                </Text>
            </View>
        );
    };




      const searchFilterFunction = (text) => {
        console.log('We Well Implement this later')
        // setSearch_text(text);  
        //   const newData = contacts.filter(item => {      
        //     const itemData = `${item.name.toUpperCase()} ${item.phoneNumbers.map(phone => phone.toUpperCase())}`
        //     const textData = text.toUpperCase();
        //     return itemData.indexOf(textData) > -1;    
        //   });
        // setSearchData(newData)
      };

      return (
        <View style={styles.container}> 
          <StatusBar barStyle="dark-content" backgroundColor="#99c0ff"  /> 
          <SafeAreaView>
          
            <View style={styles.search_view} >
                <FontAwesome name='search' size={20} color='#fff' style={{}} />
                <TextInput 
                  style={{
                    backgroundColor:"rgba(135, 135, 135, .1)", 
                    height:35,
                    borderRadius:10,
                    paddingHorizontal:10,
                    fontSize:12, 
                    color:"#fff",
                    minWidth:Dimensions.get("screen").width - 90 
                  }}
                  placeholder="Search contact here"
                  placeholderTextColor="#fff"
                  value={search_text}
                  onChangeText={(text) => searchFilterFunction(text)}
                />
                <Entypo name="cross" size={20} color={search_text.length === 0 ?'black':'#fff'}
                  onPress={() => searchFilterFunction("")}
                />
            </View>
        
            {!loading 
            ? 
              <SectionList
                sections={searchdata}
              
                renderItem={({item}) => (
                <RenderItem  item={item} />
                )} 
                legacyImplementation={true}
                horizontal={false}
                windowSize={150}
                removeClippedSubviews={false}
                initialNumToRender={20}
                updateCellsBatchingPeriod={30}
                numColumns={1}
                onEndReachedThreshold={0.07}
                maxToRenderPerBatch={30}
                getItemLayout={(data, index) => (
                  {length: 54, offset: 54 * index, index}
                )}
                //refreshing={true}
                maxToRenderPerBatch={50}
                keyExtractor={(item) =>{
                  return item.key.toString()
                }}
                renderSectionHeader={({section}) =>(
                  <View style={styles.section_title}>
                      <Text style={[styles.text,{color:"#fff", fontWeight:"bold", fontSize:16,}]}>{section.title}</Text>
                  </View>
              )}
                ListEmptyComponent={renderMessage}                                       
              />
            :
            <ActivityIndicator size="large" color="red" />
            }
          </SafeAreaView>
        </View>
      );
    }

    const styles = StyleSheet.create({
      container:{
        flex:1,
        alignItems:"center",
        backgroundColor:"#8ab7ff",
      // backgroundColor:"white",
        justifyContent:"center",
      },
      search_view:{
        flexDirection:"row",
        backgroundColor:"black",
        minWidth:Dimensions.get('screen').width-10,
        borderRadius:10,
        marginTop:2,
        paddingHorizontal:5,
        marginHorizontal:5,
        paddingVertical:2, 
        alignItems:"center",
        justifyContent:"space-evenly"
      },
      section_title:{
        backgroundColor:"rgba(204, 223, 252, .2)",
        borderRadius:5,
        marginTop:5,
        minWidth:Dimensions.get('screen').width-10,
        paddingHorizontal:15,
        marginHorizontal:5,
        paddingVertical:3, 
      },
      text:{
        fontSize:12,
        color:'white',
      },
      single_contact_style:{
        backgroundColor: '#6b6b6b', 
        borderRadius:10,
        maxHeight:50,
        paddingHorizontal:10,
        marginVertical:4,
        minWidth:Dimensions.get('screen').width-10,
        marginHorizontal:5,
        flexDirection: 'row',
      },
      name_number_view:{
        justifyContent:'space-around',
        paddingVertical:5, 
        paddingHorizontal:10, 
        flexDirection: 'column'
      }
    });

    export default App;
import React,{useState,useffect,useRef,usemo}来自“React”;
从“react native”导入{SafeAreaView,Dimensions,SectionList,TextInput,FlatList,ActivityIndicator,动画,样式表,视图,文本,Permissions and Roid,StatusBar,NativeModules,TouchableOpacity};
const{MyCustomWindowManager}=NativeModules;
从“反应本机呼叫检测”导入CallDetectorManager
从“react native Contacts”导入联系人;
从“反应本机矢量图标/FontAwesome”导入FontAwesome;
从“反应本机矢量图标/邪恶图标”导入邪恶图标
从“反应本机向量图标/Entypo”导入Entypo
从“反应本机矢量图标/Ionicons”导入图标
常量RenderItem=({item})=>{
if(item.phoneNumbers.length!==0){
返回UseMoom(()=>{
返回(
item.PhoneNumber.map(电话=>(
{item.name}
{电话}
))
)
}, []);
}else{return null}
}
常量应用=()=>{
const[contacts,setContacts]=useState([])
常量[searchdata,setSearchData]=useState([])
常量[loading,setLoading]=useState(true)
常量[搜索文本,设置搜索文本]=使用状态(“”)
const[permission,setPermission]=useState(false)
useffect(()=>{
PermissionsAndroid.requestMultiple([
PERMISSIONS和roid.PERMISSIONS.READ\u PHONE\u STATE,
PERMISSIONS和roid.PERMISSIONS.READ_联系人
])。然后((结果)=>{
setPermission(结果['android.permission.READ_CONTACTS']);
}).catch((错误)=>{
console.log(错误)
})
},[]);
useffect(()=>{
PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_CONTACTS)。然后((res)=>{
如果(res){
Contacts.getAll().then(contacts1=>{
让项目=[]
联系人1.forEach((项目,索引)=>{
推({
关键词:索引,,
名称:item.displayName,
phoneNumbers:[…新设置(item.phoneNumbers.map(x=>x.number.replace(/-|\s/g,“”)))]
})
})
设置联系人(项目)
getData();
})
}否则{
警报(“请启用权限”);
}
})
},[联系人])
常量getData=()=>{
让contactArr=[];
设aCode=“A”。charCodeAt(0);
for(设i=0;i{
返回项。名称[0]。toUpperCase()==currChar;
});
如果(currContacts.length>0){
currContacts.sort((a,b)=>a.name.localeCompare(b.name))
obj.data=电流触点;
触点推力(obj);
}
}
设置搜索数据(contactArr)
设置加载(假);
}
const renderMessage=()=>{
返回(
无接触
);
};
const searchFilterFunction=(文本)=>{
log('我们稍后会很好地实现它')
//设置搜索文本(文本);
//const newData=contacts.filter(项=>{
//const itemData=`${item.name.toUpperCase()}${item.phoneNumbers.map(phone=>phone.toUpperCase())}`
//const textData=text.toUpperCase();
//返回itemData.indexOf(textData)>-1;
//   });
//setSearchData(新数据)
};
返回(
searchFilterFunction(文本)}
/>
searchFilterFunction(“”}
/>
{!正在加载
? 
(
)} 
legacyImplementation={true}
水平={false}
WindowsSize={150}
removeClippedSubviews={false}
initialNumToRender={20}
updateCellsBatchingPeriod={30}
numColumns={1}
onEndReachedThreshold={0.07}
maxToRenderPerBatch={30}
getItemLayout={(数据,索引)=>(
{长度:54,偏移量:54*索引,索引}
)}
//刷新={true}
maxToRenderPerBatch={50}
keyExtractor={(项目)=>{
return item.key.toString()
}}
renderSectionHeader={({section})=>(
{section.title}
)}
ListMPtyComponent={renderMessage}
/>
:

最后,我解决了这个问题。我使用PureComponenet来呈现我的项目,这解决了我的问题。以下是我获得帮助的一些链接

是指向我自己的git存储库的链接