masonic icon indicating copy to clipboard operation
masonic copied to clipboard

Item components seem to be replaced whenever new items are added to array

Open johtso opened this issue 2 years ago • 6 comments

I'm trying to get an understanding of what the intended behaviour is here.

I was experimenting with adding a fade-in effect to my images when they loaded by storing a boolean loaded state in the item which I would flip "onload".

What I found was that all (apart from a seemingly random few that didn't) of my images would fade in every time more data was loaded.

I thought it might be because I wasn't defining an itemKey function, but adding one didn't change the behaviour.

Do you have to provide an ItemComponent that is completely pure with no internal state that can be thrown away at any time and re-rendered?

Here's an example https://codesandbox.io/s/masonic-example-forked-ynl73q

johtso avatar May 01 '22 17:05 johtso

Seems to be working properly. It's how virtualization works - the items are unmounted when they are no longer in view. So when you scroll back up, it would trigger the useEffect for the previously loaded items.

wjdwndud0114 avatar May 08 '22 20:05 wjdwndud0114

@wjdwndud0114 The thing is, it seems the components are remounting even though they remain inside the viewport: https://www.loom.com/share/f2f2606660a14277942b985656cb7318

johtso avatar May 08 '22 20:05 johtso

I think that's some issue with your css? Try just using transition: https://codesandbox.io/s/masonic-119-help-ymeymc

wjdwndud0114 avatar May 09 '22 01:05 wjdwndud0114

This same issue is happening to me (the issue being: "Item components seem to be replaced whenever new items are added to array").

In our code, we start with a base set of items---and then after they render, we periodically push additional items to the end of the list.

I too noticed that every single item was getting re-rendered when new items were added, so I tried wrapping the component I pass to <Masonry /> in a React.memo().

That still yielded full list re-renders, so I passed React.memo() the optional props equality-checker callback so I could dig into the props comparison and see which props were changing that were causing all of my items to get re-rendered.

It turns out every item in my list is getting re-rendered because the width prop of each item is apparently changed every single time a new item is added to the list. The bizarre thing is that the width of my items in the UI is not actually changing when new items are added to my list. They remain completely static in size. I could understand the width prop should change if my screen grows horizontally or something that was actually causing my items to grow horizontally, but---again---adding items to the end of my list does not actually cause my items to grow horizontally (i.e., the items look completely the same when new items are pushed to the list).

This is a screen shot of console logs showing my first item getting re-rendered every time a new item is pushed to the end of the list. You can see each time my component is receiving a new width prop.

image

Any advice on how I can resolve this would be much appreciated.

ND56 avatar May 09 '22 20:05 ND56

Sorry, am not experiencing this and don't have time to dig / provide support. Hopefully the community can help.

jaredLunde avatar May 10 '22 03:05 jaredLunde

@ND56 can you see if you observe the same behavior if you use the useMasonry hook?

wjdwndud0114 avatar May 12 '22 01:05 wjdwndud0114