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

如何在ReactJs+XMPP开发的聊天应用中让最新未读消息以粗体显示

未读最新消息加粗实现方案

1. Redux 层状态处理

首先调整消息存储结构和状态流转逻辑:

  • 给每条消息新增isUnread布尔字段,新接收的消息默认赋值为true
  • 在XMPP新消息监听回调中,触发Redux的新增消息action,把新消息写入store时自动标记为未读
  • 新增「标记消息已读」的action,在用户进入对应会话、或滚动到消息列表最底部时触发,将对应消息的isUnread改为false

2. 组件层渲染逻辑

在React消息列表组件中做判断渲染:

  • 用useSelector从Redux中拉取当前会话的消息列表
  • 倒序遍历消息列表,找到第一条isUnread为true的消息,即为最新的未读消息
  • 渲染每条消息时,判断当前消息ID是否等于最新未读消息ID,匹配则添加加粗样式

3. 代码示例

Redux Slice 示例(基于Redux Toolkit)

import { createSlice } from '@reduxjs/toolkit'

const chatSlice = createSlice({
  name: 'chat',
  initialState: {
    // 多会话场景可按会话ID分组存储消息
    messages: []
  },
  reducers: {
    addNewMessage: (state, action) => {
      // 新消息默认标记为未读
      state.messages.push({...action.payload, isUnread: true})
    },
    markCurrentSessionRead: (state) => {
      // 将当前会话所有消息标记为已读
      state.messages.forEach(msg => msg.isUnread = false)
    }
  }
})

export const { addNewMessage, markCurrentSessionRead } = chatSlice.actions
export default chatSlice.reducer

XMPP 新消息监听

// xmpp客户端实例监听新消息事件
xmppClient.on('message', (receivedMsg) => {
  // 解析消息内容后 dispatch 到Redux
  store.dispatch(addNewMessage({
    id: receivedMsg.id,
    content: receivedMsg.body,
    senderId: receivedMsg.from,
    timestamp: Date.now()
  }))
})

消息列表组件示例

import { useSelector, useDispatch } from 'react-redux'
import { markCurrentSessionRead } from './chatSlice'

const MessageList = () => {
  const dispatch = useDispatch()
  const messages = useSelector(state => state.chat.messages)
  // 获取最新未读消息ID
  const latestUnreadMsgId = messages.slice().reverse().find(msg => msg.isUnread)?.id

  // 监听滚动事件,滚动到底部时标记所有消息已读
  const handleListScroll = (e) => {
    const isScrollToBottom = e.target.scrollHeight - e.target.scrollTop === e.target.clientHeight
    if (isScrollToBottom) dispatch(markCurrentSessionRead())
  }

  return (
    <div className="message-container" onScroll={handleListScroll}>
      {messages.map(msg => (
        <div 
          key={msg.id}
          className={`message-item ${msg.id === latestUnreadMsgId ? 'bold-unread' : ''}`}
        >
          {msg.content}
        </div>
      ))}
    </div>
  )
}

样式示例

.bold-unread {
  font-weight: 700;
}

补充说明

如果需求是所有未读消息都加粗,不需要单独判断最新未读ID,直接在渲染时判断msg.isUnread为true时添加加粗样式即可。

内容的提问来源于stack exchange,提问作者Wani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:48:02