react-native - react native flat list 重新渲染所有项目并添加每个新项目
问题描述
我有一个简单的聊天系统,它与 express/socket io 一起运行,并与 FlatList 进行原生反应以呈现消息。
我的问题是,每次我接收或发送消息时,IE:向显示的消息添加消息,整个 FlatList 都会重新呈现,这会使它闪烁,正如您在下面的视频中看到的那样,看看这里发生了什么!
我将消息添加到平面列表的方式如下:
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]);
平面列表代码本身如下:
<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} />
}
/>
页面中唯一的useEffect语句如下:
useEffect(() => {
const unsubscribe = navigation.addListener("focus", loadMessage);
// Return the function to unsubscribe from the event so it gets removed on unmount
return unsubscribe;
},[navigation]);
当我收到消息时,这就是我所做的::
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);
}
});
当我使用这个应用程序发短信时,它会像你们在视频中看到的那样,然后重新渲染组件变得非常疯狂,直到聊天一段时间后我得到以下错误:
PayloadTooLargeError: request entity too large
如果我继续这样做,我会得到(我只在 android 设备上得到以下内容,我不确定它是否与手头的问题有关-我将其包括在内以防万一-):
Warning: Please report: Excessive number of pending callbacks: 501. Some pending callbacks that might have leaked by never being called from native code:
之后,该应用程序只是冻结了一段时间......
解决方案
推荐阅读
- react-native - 如何将参数从反应本机 webview 传递到存储在 xcode 中的外部 javascript 文件函数
- oracle - 如何从 oracle 中的 MGMT_JOB 中删除作业?
- java - 如何使用 jpa(休眠)从表中仅选择 postgres jsonb 列
- amazon-web-services - 获取范围内的查询结果 Redshift
- java - 如何使用 Jackson 修复带有 Jersey 客户端的 MessageBodyProviderNotFoundException?
- android - 更新到 Android Studio 3.5 后,2019 年构建项目需要很长时间
- neural-network - 当我们使用激活函数时,我们如何知道一个神经元被激活了
- scala - 如何按特定类的数据框分组
- reactjs - 状态已正确更新和记录,但 HTML 中的值仍然错误
- laravel - Laravel 分页从 ?page=1 更改为 /page/1