
本文介绍在基于 django channels 和 react 的实时聊天应用中,通过区分消息发送者身份,动态为当前用户与他人消息应用不同 css 样式(如背景色)的完整实现方案。
本文介绍在基于 django channels 和 react 的实时聊天应用中,通过区分消息发送者身份,动态为当前用户与他人消息应用不同 css 样式(如背景色)的完整实现方案。
在构建实时聊天界面时,视觉上清晰区分“自己发送的消息”和“他人发送的消息”是提升用户体验的关键细节。核心思路是:每条消息数据必须携带发送者标识(如 username),前端据此动态分配 CSS 类名,再通过样式控制呈现效果。
首先,修改消息发送逻辑,确保每条消息都附带 sentBy 字段:
function theone(e) {
e.preventDefault();
chatSocket.send(
JSON.stringify({
message: myInput,
sentBy: currentUser?.username || 'anonymous', // ✅ 显式传入当前用户标识
})
);
setMyInput2('');
}
其次,在 WebSocket 消息接收端,避免直接渲染 JSX 元素到 state 中(这是反模式:将 UI 组件存入 state 会破坏可维护性、阻碍重渲染优化,并导致 ref 失效)。应仅保存纯数据对象:
chatSocket.onmessage = function (e) {
if (ran === true) {
const data = JSON.parse(e.data);
// ✅ 仅存消息数据,不含 JSX
setMessages((old) => [...old, { message: data.message, sentBy: data.sentBy }]);
}
};
接着,在 JSX 渲染层,使用 .map() 安全地生成消息列表,并根据 sentBy 与 currentUser.username 是否匹配,动态绑定类名:
<div classname="messages-container">
{messages.map((msg, idx) => (
<p key="{idx}" index id classname="{" msg.sentby="==" currentuser :>
<strong>{msg.sentBy}:</strong> {msg.message}
</p>
))}
</div>
最后,定义对应 CSS 类(推荐使用 CSS Modules 或 CSS-in-JS 避免全局污染,此处以普通 CSS 为例):
.message-current-user {
background-color: #4CAF50; /* 绿色,表示自己 */
color: white;
padding: 8px 12px;
border-radius: 16px 16px 4px 16px;
margin: 4px 0;
max-width: 70%;
text-align: right;
margin-left: auto;
}
.message-other-user {
background-color: #e0e0e0; /* 浅灰,表示他人 */
color: #333;
padding: 8px 12px;
border-radius: 16px 16px 16px 4px;
margin: 4px 0;
max-width: 70%;
text-align: left;
margin-right: auto;
}
⚠️ 重要注意事项:
- 安全提醒:sentBy 字段不应完全由前端构造并信任。理想情况下,Django Channels 后端应在广播消息前注入真实发送者信息(如 user.username),防止恶意客户端伪造身份。本文方案适用于开发/学习场景,上线前务必后端校验并覆盖该字段。
- 性能优化:若消息量大,建议结合 React.memo 包裹单条消息组件,并使用 useCallback 缓存渲染函数。
- 可访问性:为不同用户消息添加 aria-label(例如 aria-label="来自 ${msg.sentBy} 的消息")可提升屏幕阅读器体验。
通过以上结构化改造,你将获得一个语义清晰、样式可控、易于扩展的双色消息系统——既满足基础需求,也为后续气泡对齐、时间戳、已读状态等增强功能打下坚实基础。











