简体   繁体   English

为什么useEffect导致无限重新渲染?

[英]Why useEffect causing infinite rerender?

I have a Rooms component which I want to re-render when the filtering settings for the room changes.The useEffect hook for the same is:我有一个房间组件,当房间的过滤设置发生变化时,我想重新渲染它。同样的 useEffect 钩子是:

 useEffect(()=>{
        var items1=items.filter((item)=>{
            if(item.fields.price<=price)
            return item;
        })
        var items2=items1.filter((item)=>{
            if(item.fields.breakfast==breakfast)
            return item;
        })
        var items3=items2.filter((item)=>{
            if(item.fields.pets==petsAllowed)
            return item;
        })
        var items4=items3.filter((item)=>{
            if(item.fields.capacity<=capacity)
            return item;
        })
        filteredRooms=items4;
        if(items4.length!=items.length)
        setFilteredRooms(items4);
    })

I havent added filteredRooms as a dependency but still its causing infinte re-rendering.我没有添加filteredRooms 作为依赖,但它仍然导致无限重新渲染。

When using useEffect without an array of dependencies it will be executed whenever some state changes.当使用没有依赖数组的 useEffect 时,只要某些状态发生变化,就会执行它。 And your array comparison if(items4!=items) always returns true .并且您的数组比较if(items4!=items)总是返回true So the state is always updated.所以状态总是更新的。 This generates the loop.这会生成循环。

Try something like:尝试类似:

 useEffect(()=>{
    var items1=items.filter((item)=>{
        if(item.fields.price<=price)
        return item;
    })
    var items2=items1.filter((item)=>{
        if(item.fields.breakfast==breakfast)
        return item;
    })
    var items3=items2.filter((item)=>{
        if(item.fields.pets==petsAllowed)
        return item;
    })
    var items4=items3.filter((item)=>{
        if(item.fields.capacity<=capacity)
        return item;
    })
    filteredRooms=items4;
    if(items4.equals(items))
    setFilteredRooms(items4);
},[])

I have a Rooms component which I want to re-render when the filtering settings for the room changes.我有一个房间组件,当房间的过滤设置发生变化时,我想重新渲染它。

There is likely not a reason to store the filtered array in state.可能没有理由将过滤后的数组存储在状态中。 Instead you should be using useMemo , but if items is small you could also just compute the filtered array directly in the render function.相反,您应该使用useMemo ,但如果items很小,您也可以直接在渲染函数中计算过滤后的数组。

Also there is no need to call .filter multiple times, once is enough.也不需要多次调用.filter ,一次就足够了。

const filteredRooms = useMemo(
  () => items.filter(
    ({fields}) => fields.price === price && 
                  fields.breakfast === breakfast &&
                  fields.pets === petsAllowed &&
                  fields.capacity <= capacity
  ),
  [items, price, breakfast, petsAllowed, capacity]
)
// use filteredRooms as needed

This will update filteredRooms whenever items , price , breakfast , petsAllowed or capacity changes.每当itemspricebreakfastpetsAllowedcapacity发生变化时,这将更新filteredRooms

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM