如何通过useSWR对比重验证前后数据,计算数组长度差值?
获取SWR重验证前的数组长度,实现新元素依次显示
你可以用useRef来存储上一次的数组长度——这是最适合的方案,因为useRef的.current属性不会触发组件重渲染,刚好用来保存这种只做对比用的历史状态。
下面是修正后的完整代码,同时修复了原代码里循环逻辑、定时器清理等潜在问题:
import { useState, useEffect, useRef } from 'react'; import useSWR from 'swr'; // 假设你的接口请求函数 const fetcher = (...args) => fetch(...args).then(res => res.json()); export default function MessageComponent() { // 开启30秒自动重验证拉取数据 const { data } = useSWR('/api/messages', fetcher, { revalidateInterval: 30000 }); const messages = data?.messages || []; // 存储上一次的数组长度 const prevMessagesLengthRef = useRef(messages.length); const [currentMessage, setCurrentMessage] = useState(messages[0] || null); useEffect(() => { // 计算新增元素数量 const newCount = messages.length - prevMessagesLengthRef.current; // 只有有新增元素时才执行逻辑 if (newCount > 0) { // 30秒均分每个元素的显示间隔 const delayPerItem = (30 / newCount) * 1000; // 精准定位新增元素的索引范围 const startIndex = prevMessagesLengthRef.current; const endIndex = messages.length - 1; // 用定时器依次显示新增元素 const timers = []; for (let i = startIndex; i <= endIndex; i++) { const timer = setTimeout(() => { setCurrentMessage(messages[i]); }, (i - startIndex) * delayPerItem); timers.push(timer); } // 清理定时器,避免内存泄漏 return () => { timers.forEach(timer => clearTimeout(timer)); }; } // 更新历史长度为当前长度,供下次重验证使用 prevMessagesLengthRef.current = messages.length; }, [messages]); return ( <div> {currentMessage ? ( <p>{currentMessage.content}</p> ) : ( <p>暂无消息</p> )} </div> ); }
核心要点:
useRef存历史长度:初始化时设为当前数组长度,每次处理完新增元素后更新为当前长度,下次重验证就能拿到上一次的数值。- 精准定位新增元素:用旧长度当起始索引,新长度减一当结束索引,避免原代码循环逻辑的索引错误。
- 定时器清理:组件卸载或下次重验证前清空定时器,防止内存泄漏或重复执行。
- 空值判断:加入
data?.messages || []这类判断,避免数据未加载时出现报错。
内容的提问来源于stack exchange,提问作者Jeppe Madsen
相关产品推荐
相关产品推荐

