如何为单个RoomId仅显示一个ChatCard,避免重复渲染?
问题修复:单RoomId对应单个ChatCard
问题说明
开发类Instagram私信盒子时,同一RoomId的多条消息会渲染多个ChatCard,需实现每个RoomId仅显示一个ChatCard。当前代码按username分组,无法保证房间唯一性,需改为按房间唯一标识RoomId分组。
修复方案
核心是将数据分组依据从username替换为RoomId,利用RoomId的唯一性确保每个房间只生成一个ChatCard,同时更新React渲染的key为RoomId,避免重复渲染。
修改后的代码
import { Text, View } from 'react-native' import React, { useState, useEffect } from 'react' import { ScrollView, TextInput } from 'react-native-gesture-handler' import { Ionicons } from '@expo/vector-icons'; import { formHead } from '../../CommonCss/FormCss'; import ChatCard from '../../Cards/ChatCard'; import styles from './styles'; import AsyncStorage from '@react-native-async-storage/async-storage'; const MainChat = ({ navigation }) => { const [keyword, setKeyword] = useState('') const [chats, setChats] = useState({}); useEffect(() => { const fetchData = async () => { try { const userDataString = await AsyncStorage.getItem('user'); const MyData = await JSON.parse(userDataString); const response = await fetch(`http://10.0.2.2:3000/g`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ MyUserId: MyData.user._id }) }); const data = await response.json(); let tempChats = {}; data.forEach((chat) => { // 按RoomId分组,替代原username分组逻辑 if (!tempChats[chat.RoomId]) { tempChats[chat.RoomId] = { roomId: chat.RoomId, username: chat.senderUsername, latestMessage: chat.lastMessage, messages: [chat.lastMessage] }; } else { // 更新房间最新消息,保留所有消息记录 tempChats[chat.RoomId].latestMessage = chat.lastMessage; tempChats[chat.RoomId].messages.push(chat.lastMessage); } }); setChats(tempChats); await AsyncStorage.setItem('chats', JSON.stringify(tempChats)); } catch (error) { console.error(error); } }; (async () => { const cachedChats = await AsyncStorage.getItem('chats'); if (cachedChats) { setChats(JSON.parse(cachedChats)); } else { fetchData(); } })(); }, []); return ( <ScrollView style={styles.container}> <Ionicons name="arrow-back" size={24} color="grey" style={styles.backbtn} onPress={() => navigation.navigate("home")} /> <View style={styles.searchSection}> <Text style={formHead}>Your Chats</Text> <TextInput placeholder='Search' style={styles.searchbar} onChangeText={(text) => setKeyword(text)} /> </View> <View style={styles.ChatSection}> { chats ? Object.values(chats) .filter((chat) => { if (keyword === '') { return chat; } else if ( chat.username.toLowerCase().includes(keyword.toLowerCase()) || chat.latestMessage.toLowerCase().includes(keyword.toLowerCase()) ) { return chat; } return false; }) .map((chat) => { // 用roomId作为唯一key,确保渲染稳定性 return <ChatCard key={chat.roomId} chat={chat} />; }) : null } </View> </ScrollView> ) } export default MainChat
关键修改点
- 分组逻辑替换:从按
username分组改为按RoomId分组,保证同一房间的消息合并到同一个对象中。 - 渲染key更新:使用
roomId作为ChatCard的key,避免因同一用户多房间导致的key重复问题。 - 消息优化:新增
latestMessage字段用于聊天列表展示,同时保留messages数组存储房间所有消息。
内容的提问来源于stack exchange,提问作者stylx
相关产品推荐
相关产品推荐

