ReactJS中如何在用户每次发送新消息时添加新的<p>标签?
解决React聊天消息覆盖问题
问题核心:你用单个React元素作为sendMsg的状态值,每次发送新消息时都会直接替换掉旧的元素,自然只会显示最后一条消息。要实现消息累积,得把状态改成存储消息内容的数组,再通过遍历数组渲染所有消息。
修改步骤
- 调整状态定义
把单个元素的状态改成空数组,用来存储所有用户发送的消息内容:
// 替换原来的const [sendMsg, setSendMsg] = useState(<p></p>); const [messages, setMessages] = useState([]);
- 更新消息发送逻辑
修改handleSendKey,每次发送时把新消息追加到数组末尾(使用函数式更新确保拿到最新的状态):
const handleSendKey = () => { if (transcriptValue.trim()) { // 避免发送空消息 setMessages(prevMessages => [...prevMessages, transcriptValue.trim()]); } };
- 渲染所有用户消息
原来的单个<li>替换成遍历messages数组,为每条消息生成一个独立的<li>:
<ul className="chatbot__box" id="ul-chatbot-box"> <li className="chatbot__chat incoming" id="li-incoming-msg"> <span className="material-symbols-outlined">smart_toy</span> <p>Hi there, How can I help you today?</p> </li> <div id="div-btn-res" className="btn" style={{ display: 'none' }}></div> {/* 遍历messages数组渲染所有用户消息 */} {messages.map((msg, index) => ( <li key={index} className="chatbot__chat outgoing"> <p>{msg}</p> </li> ))} </ul>
- 优化键盘事件处理(可选)
原来的handleKeyDown里直接设置transcriptValue可能会和textarea的onChange冲突,建议把输入框的内容同步放到onChange里,handleKeyDown只处理回车逻辑:
// 假设你的textarea是这样的 <textarea value={transcriptValue} onChange={(e) => setTranscriptValue(e.target.value)} onKeyDown={handleKeyDown} /> // 修改handleKeyDown const handleKeyDown = (event) => { if (event.key === 'Enter' && !event.shiftKey) { // 允许Shift+Enter换行 event.preventDefault(); // 阻止默认换行行为 handleSendKey(); setTranscriptValue(''); } };
这样修改后,每次发送消息都会新增一个<li>元素,而不是覆盖之前的内容,完美实现消息累积展示。
内容的提问来源于stack exchange,提问作者Vinit_2311
相关产品推荐
相关产品推荐

