为了账号安全,请及时绑定邮箱和手机立即绑定

React useEffect() :比较两个对象数组是否相等的最有效方法

React useEffect() :比较两个对象数组是否相等的最有效方法

拉丁的传说 2023-10-14 15:41:58
我有一个 useEffect() ,当对象数组发生变化时应该触发它。  useEffect(() => {       setNotesToRender(props.notes)   }, [props.notes]);useEffect 依赖项无法比较对象数组,因此上例中的 useEffect() 触发的次数超出了需要的次数。我只希望在数组不同时触发 useEffect() 。应触发更新的数组示例array1 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'three'}] array2 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'four'}]到目前为止我测试过的事情是:props.notes.length --> 可以工作,但不可靠 - 原因很明显:)...props.notes --> 如果数组为空则不起作用 - 并且可能会导致严重的性能问题?比较两个对象数组的最有效方法是什么?数组可能包含超过 1000 个对象。亲切的问候/K更新 我需要稍后使用文本搜索过滤掉某些“注释”,这就是我使用 React 状态的原因。我的示例代码中没有显示这一点。
查看完整描述

3 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

最有效的方法是什么

最有效的方法可能是针对这种特定形状的数据进行自定义比较。您可以使用JSON.stringify或其他一些通用比较函数,但由于显而易见的原因,它不太可能是最有效的。

因此,在您的示例中,一个简单的比较函数可能看起来像 ->

const array1 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'three'}];

const array2 = [{id:1,title:'one'},{id:2,title:'two'},{id:3,title:'four'}];


const arrayIsEqual = (a1, a2) => 

  a1 === a2 ||

  a1.length === a2.length &&

  a1.every((f,i) => 

    f.id === a2[i].id &&

    f.title === a2[i].title

  )

  

  

//tests

const a1clone = [...array1];


//different arrays not equal

console.log(arrayIsEqual(array1, array2)); //false


//different arrays equal

console.log(arrayIsEqual(array1, a1clone)); //true


//different arrays same values, but different order

a1clone.reverse();

console.log(arrayIsEqual(array1, a1clone)); //false


//same arrays, fastest check

console.log(arrayIsEqual(array1, array1)); //true


查看完整回答
反对 回复 2023-10-14
?
隔江千里

TA贡献1906条经验 获得超10个赞

首先1k个对象并不是一个大量的对象,但是回到问题:最简单的方法是使用

JSON.stringify(object1) === JSON.stringify(object2);

但这并不是最有效的,当性能成为问题时,我能想到的最明智的事情是使用元属性,例如,version每当我们以任何方式更新对象时,我们也会增加版本。然后你所要做的就是根据 id + version 映射检查两个数组。

如果不需要第二个选项,您可以使用lodash.deepCompare或创建自己的函数。


查看完整回答
反对 回复 2023-10-14
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

确实,useEffect无法比较对象数组,因此让useEffect钩子运行。

但你可以做的是添加一个if-statement是否JSON.stringified notesToRender and JSON.stringified props.notes相等。(或者你可以使用lodash/isEqual)来阻止设置状态方法运行。

useEffect但是,如果您认为这仍然不是一个有效的解决方案,我们首先必须看看您为什么需要。

从您的代码来看,我认为您正在useState根据传入的道具设置一个钩子。

再想一想,为什么不考虑直接渲染道具呢。

来自官方 React 文档页面:
https://reactjs.org/docs/thinking-in-react.html#step-3-identify-the-minimal-but-complete-representation-of-ui-state

  1. 它是通过 props 从父级传递的吗?如果是这样,它可能不是状态。

  2. 随着时间的推移它会保持不变吗?如果是这样,它可能不是状态。

  3. 您可以根据组件中的任何其他状态或道具来计算它吗?如果是这样,那么它就不是状态。


查看完整回答
反对 回复 2023-10-14
  • 3 回答
  • 0 关注
  • 236 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信