Javascript 传递由array.filter计算的值始终会导致在React中渲染

Javascript 传递由array.filter计算的值始终会导致在React中渲染,javascript,reactjs,Javascript,Reactjs,我有一个组件,它根据array.filter计算要传递的值。糟糕的是,即使阵列的元素完全相同,也会因为道具每次都改变而导致新的渲染 该组件依赖于根据以下状态计算的值: const [targets, setTargets] = useState<Target[]>([]); 每次父级渲染时-如果将id传递给getTargets,则Map组件将重新渲染。如果传递了未定义,则不会重新渲染。这对我来说很有意义,因为如果传入一个未定义的,它每次只返回相同数组的状态 但是,如

我有一个组件,它根据array.filter计算要传递的值。糟糕的是,即使阵列的元素完全相同,也会因为道具每次都改变而导致新的渲染

该组件依赖于根据以下状态计算的值:

        const [targets, setTargets] = useState<Target[]>([]);
每次父级渲染时-如果将
id
传递给
getTargets
,则
Map
组件将重新渲染。如果传递了
未定义
,则不会重新渲染。这对我来说很有意义,因为如果传入一个
未定义的
,它每次只返回相同数组的状态

但是,如果我传递了一个
id
Map,则会因为从
filter
方法创建了一个新数组而重新渲染,即使该元素的成员不变(例如,每次传递相同的2个元素)。此数组包含来自
目标
的原始元素。糟糕的是,在每次渲染时,
Map
组件都将其视为传入了新目标,即使参数没有更改。这是不好的,因为当目标发生变化时,
Map
中会产生额外的效果

如何计算作为道具传递的数组子集,但如果元素相同,则不会触发对子元素的更改?

我想用
usemo
或者别的什么,我需要它来记住输入并保存输出,只要目标没有改变(这会导致回调产生一个新函数),这个函数就是纯函数。

你可以使用
usemo()

const groupTargets = useMemo(()=>targets.filter(target => target.group === groupId),[targets]);
它只在目标改变时运行 或者在Map.js中,您可以这样做

export default React.memo(Map)
这将比较道具并在道具更改时重新播放

但是
Kent C Dodds
不鼓励始终使用
useCallback()
UseMoom()
React.memo()
,因为执行这些操作的成本高于
重新招标的成本。请参阅您可以使用
usemo()
进行此操作

const groupTargets = useMemo(()=>targets.filter(target => target.group === groupId),[targets]);
它只在目标改变时运行 或者在Map.js中,您可以这样做

export default React.memo(Map)
这将比较道具并在道具更改时重新播放


但是
Kent C Dodds
不鼓励始终使用
useCallback()
UseMoom()
React.memo()
,因为执行这些操作的成本高于
重新招标的成本。如果道具没有更改,React将不会进行物理重新渲染。但它仍将调用您的函数,。是的,如果你有一些昂贵的东西,你可以
usemo
,如果它是异步的,你也可以使用
useffect
,但别忘了传递导致它改变的道具。例如,
usemo(expensiveStuff,[prop1,prop2])
等等。ps,当我说props时,我也指props&state。如果道具没有改变,React不会进行物理重新渲染。但它仍将调用您的函数,。是的,如果你有一些昂贵的东西,你可以
usemo
,如果它是异步的,你也可以使用
useffect
,但别忘了传递导致它改变的道具。例如,
useMemo(expensiveStuff,[prop1,prop2])
等等。ps,当我说props时,我也指props和state。谢谢,这对我的解决方案很有用。我遇到的问题是,如果groupId可以改变很多,或者通过循环传入(可能存在于100个元素上?)。如果有useMemo,它接受一个参数并返回一个存储的值,那就太好了。这可能吗?(标记为已接受,适用于我的情况,谢谢!)谢谢,这适用于我的解决方案。我遇到的问题是,如果groupId可以改变很多,或者通过循环传入(可能存在于100个元素上?)。如果有useMemo,它接受一个参数并返回一个存储的值,那就太好了。这可能吗?(标记已接受,适用于我的情况,谢谢!)
const groupTargets = useMemo(()=>targets.filter(target => target.group === groupId),[targets]);