You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为单个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 08:56:09