[英]react-hooks/exhaustive-deps warning or infinite loop?
I have a mediaType
variable, when it change, currentSelectedMedia
need to be filtered.我有一个
mediaType
变量,当它改变时, currentSelectedMedia
需要被过滤。 In this scenario, I get react-hooks/exhaustive-deps
warning.在这种情况下,我收到
react-hooks/exhaustive-deps
警告。
/**
data example:
currentSelectedMedia = [
{ id: '1', mediaType: '1', name: 'facebook'},
{ id: '2', mediaType: '2', name: 'twitter'}
]
**/
useEffect(() => {
setCurrentSelectedMedia(currentSelectedMedia.filter(item => item.mediaType === mediaType))
}, [mediaType])
If I add currentSelectedMedia
to the dependency array,infinite loop is caused.如果我将
currentSelectedMedia
添加到依赖数组中,则会导致无限循环。
the warning is right according to the rule, the reason of infinite loop is also obvious.警告按规则是正确的,死循环的原因也很明显。 But how can I get escape?
但是我怎么能逃脱呢?
You are getting react-hooks/exhaustive-deps warning or infinite loop because your useEffect
hook gets trigger every time there is a change in mediaType
state;您收到 react-hooks/exhaustive-deps 警告或无限循环,因为每次
mediaType
state 发生变化时都会触发您的useEffect
挂钩; And in your useEffect
method you are setting the value of mediaType
state;在您的
useEffect
方法中,您正在设置mediaType
state 的值;
To solve this problem either you can have two different state or just a normal function which sets the mediaType
or just create a variable which filters the data when your state gets change.要解决此问题,您可以使用两个不同的 state 或仅设置 mediaType 的普通
mediaType
或仅创建一个变量以在 state 发生更改时过滤数据。 That depends on how you are setting your mediaType state from other places.这取决于您如何从其他地方设置您的 mediaType state。
const filteredData = currentSelectedMedia.filter(item => item.mediaType === mediaType);
Use filteredData to render the data.使用filteredData 来呈现数据。
I believe what you want is getting the filtered selected media.我相信您想要的是获得过滤后的选定媒体。
However, using useEffect in this instance may not be the most appropriate.但是,在这种情况下使用 useEffect 可能不是最合适的。 You may want to consider useMemo instead.
您可能需要考虑使用 useMemo 。
const filteredMedia = useMemo(() => {
return currentSelectedMedia.filter(item => item.mediaType === mediaType)
}, [currentSelectedMedia, mediaType] )
You may then use filteredMedia
in your rendering.然后,您可以在渲染中使用
filteredMedia
媒体。
The value will only be re-filtered when currentSelectedMedia
or mediaType
changed.仅当
currentSelectedMedia
或mediaType
更改时才会重新过滤该值。
The above is almost equivalent to以上几乎等同于
const filteredMedia = currentSelectedMedia.filter(item => item.mediaType === mediaType)
The difference is - useMemo is "memorized", so it won't be recalculated on every render.不同之处在于 - useMemo 是“记忆的”,因此不会在每次渲染时重新计算。
Small performance difference for small arrays and calculation, visible performance boost when you are handling huge list and complicated calculations.小型 arrays 和计算的性能差异很小,当您处理大量列表和复杂计算时,性能明显提升。
useEffect
will trigger on mount and each time one of it's dependencies change. useEffect
将在挂载时触发,并且每次它的依赖项之一发生更改时。 If you add currentSelectedMedia
to it's dependency list and you are also modifying currentSelectedMedia
within your useEffect
causing the infinite loop.如果您将
currentSelectedMedia
添加到它的依赖项列表中,并且您还在useEffect
中修改currentSelectedMedia
导致无限循环。
I would simply use the same logic that would change mediaType
(most likely an [action]Handler
function) and setCurrentSelectedMedia
there.我会简单地使用相同的逻辑来改变
mediaType
(很可能是一个[action]Handler
函数)和那里的setCurrentSelectedMedia
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.