优化useEffect数组对象修改逻辑并实现数据差异对比
代码优化方案
先梳理原代码存在的核心问题:
oldData从localStorage取出后未做JSON解析,直接使用会导致后续对比逻辑全部失效arrayIsEqual函数定义后未传入参数调用,直接判断if(arrayIsEqual)永远为真(函数本身是真值)- 使用
Array.includes()对比对象是否存在,由于对象是引用类型,严格相等判断无法匹配内容相同的不同对象,导致差异计算错误 finalArray的合并逻辑错误,将数组和对象直接展开合并会破坏原数据结构- 存在重复的
localStorage.setItem调用逻辑
优化后的实现方案
我们可以封装成自定义Hook,复用逻辑同时提升代码可读性和性能:
// 自定义Hook:useTrackNewData.js import { useEffect } from 'react'; const localStorageKey = 'laboratoryData'; // 辅助函数:对比两个数据项是否相等(根据id和name) const isItemEqual = (itemA, itemB) => itemA.id === itemB.id && itemA.name === itemB.name; // 辅助函数:从旧数据中找出新增的项 const getNewItems = (newDataList, oldDataList) => { return newDataList.filter(newItem => !oldDataList.some(oldItem => isItemEqual(newItem, oldItem)) ); }; export const useTrackNewData = (data) => { useEffect(() => { if (!data?.data) return; // 空数据直接返回 // 读取并解析本地存储的旧数据 const storedOldData = localStorage.getItem(localStorageKey); const oldDataList = storedOldData ? JSON.parse(storedOldData) : []; // 情况1:本地无旧数据,直接存储新数据 if (oldDataList.length === 0) { localStorage.setItem(localStorageKey, JSON.stringify(data.data)); return; } // 情况2:对比数据是否完全一致 const isDataEqual = data.data.length === oldDataList.length && data.data.every((item, index) => isItemEqual(item, oldDataList[index])); if (isDataEqual) { localStorage.setItem(localStorageKey, JSON.stringify(data.data)); return; } // 情况3:为新增项添加isNew属性,生成最终数据数组 const newItems = getNewItems(data.data, oldDataList); const finalDataList = data.data.map(item => { const isNew = newItems.some(newItem => isItemEqual(item, newItem)); return isNew ? {...item, isNew: true} : item; }); // 存储最终数据 localStorage.setItem(localStorageKey, JSON.stringify(finalDataList)); }, [data]); };
使用方式
在组件中直接引入并使用:
import { useTrackNewData } from './useTrackNewData'; const YourComponent = ({ data }) => { useTrackNewData(data); // 组件其他逻辑 return <div>...</div>; };
优化点说明
- 封装自定义Hook,将数据追踪逻辑与组件解耦,提升复用性
- 拆分辅助函数(
isItemEqual、getNewItems),让单一函数职责更清晰,便于维护和测试 - 修复了原代码中对象对比、数据解析的核心错误
- 简化条件分支,减少重复的存储操作
- 添加空值判断,避免因
data或data.data为空导致的报错
内容的提问来源于stack exchange,提问作者CodeAgainst
相关产品推荐
相关产品推荐

