如何配置React的useEffect仅监听messages.length递增以实现新消息自动滚底
实现方案
React没有内置直接获取上一轮props/状态的API,你可以通过useRef存储历史消息长度实现需求,useRef的更新不会触发组件重渲染,用来存储这类不需要触发视图更新的缓存值非常合适。
具体修改步骤
- 从react中引入
useRef - 声明ref变量存储上一次的消息长度
- 在useEffect中增加长度对比逻辑,仅当当前长度大于上一次长度时才执行滚底操作
修改后的完整代码
import { useState, useEffect, useRef } from 'react'; //Components: import ChatBubble from './ChatBubble'; import ScrollButton from './ScrollButton'; export default function MessagesBoard({ messages }) { //useState: const [showScrollButton, setShowScrollButton] = useState(false); // 存储上一次的消息长度 const prevMsgLengthRef = useRef(messages.length); //Event: Scroll to bottom upon new message useEffect(() => { const currentLength = messages.length; // 仅当消息长度递增时才触发滚底 if (currentLength > prevMsgLengthRef.current) { scrollDown(); } // 每次执行后更新存储的历史长度 prevMsgLengthRef.current = currentLength; }, [messages.length]); const scrollDown = () => { // 你的原有滚底逻辑 }; return ( <div className='chatMessagesBlock'> <div className='messagesCanvas'> {messages.map((chatMessage) => { // 补充:原代码缺少解构步骤,这里需要从chatMessage中取出对应字段 const { msgID, sender, msgContent } = chatMessage; return ( <ChatBubble key={msgID} msgID={msgID} sender={sender} msgContent={msgContent} /> ); })} </div> <ScrollButton showScrollButton={showScrollButton} scrollDown={scrollDown} /> </div> ); }
可选优化思路
如果你需要更精确的判断(比如同时新增1条删除1条,长度不变但有新消息的极端场景),可以改为存储上一次最新消息的id,对比最新一条消息的id是否发生变化,来判断是否有新消息到达。
内容的提问来源于stack exchange,提问作者Tal Kohavy
相关产品推荐
相关产品推荐

