i have a smiple chat system that runs with express/socket io and react native with FlatList to render the messages.
my problem is that everytime i recieve or send a message , I.E : add a message to the displayed messages , the whole FlatList gets rerendered which amkes it flicker as you see in the following video see what happens here!!
the way i'm adding the messages to the flatlist is as follows:
const [messages, setMessages] = useState<any[]>([WELCOME_MESSAGE]);
// the following line i use when i get a new message from the server ... and the definition in the beginning of the component (so the problem isn't here...)
setMessages([newMessage, ...messages]);
and the flat list code itself is as follows :
<FlatList
inverted
style={{}}
contentContainerStyle={{
flexGrow: 1,
// justifyContent: "flex-end",
paddingHorizontal: 12,
paddingBottom: 30,
}}
data={data}
renderItem={({ item }) => (
<ChatMessage data={item} key={item._id + ""} />
)}
keyExtractor={(item) => item._id}
// keyExtractor={(item) => item._id}
refreshControl={
<RefreshControl refreshing={loading} onRefresh={onUpdate} />
}
/>
the only useEffect statement in the page is as follows:
useEffect(() => {
const unsubscribe = navigation.addListener("focus", loadMessage);
// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
},[navigation]);
also when i get a message this is what i do ::
socket.on('update-chat' ,async(data : any)=>{
console.log('<<<<<<< recieve message <<<<<<<');
console.log(data);
console.log('<<<<<<< recieve message <<<<<<<');
let roomID = '' ;
await getRoomID().then((data)=>{
console.log('getting the room id and setting the hook...', data);
roomID = (data?.headers.room != null)? data.headers.room : '';
});
console.log('setting room to use in update chat...');
// TODO check if we have the room id locally...
if(roomID != null && roomID === data.roomId && roomID !== ''){
// TODO ==> just get the data and start working on the display...
// updating display...
console.log('udpate chat , rooomID : ' + roomID);
addMessage(data.message);
}else{
// TODO ==> store the roomID and then update display...
// saving the roomID for later use and then update displays...
console.log('roomID');
await useRoom.save(data.roomId||'') ;
addMessage(data.message);
}
});
when i text using this app it does as you guys saw in the video and then it becomes really crazy with the re-rendering of components until i get the following error after chatting for a while :
PayloadTooLargeError: request entity too large
and if i keep going after that i get(i'm only getting the following on android devices and i'm not sure it's connected to the issue at hand -i'm including it just in case -):
Warning: Please report: Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code:
after that the app just freezes for a while ...