Reactjs 对较大的列表进行本机分区列表优化
我有一个平面列表,最多可以有1000个项目。我已经尝试了所有的优化和现在顺利的决赛,但第一次渲染速度慢,渲染项目慢。基本上,我显示的是手机用户的联系人列表。这是我尝试过的代码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,
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存储库的链接