twobin/react-lazyload

Not working if two set of instances exist on the same page, one uses scrollContainer and one doesn't

Closed this issue · 7 comments

I have a page which contains two lists of images (images are lazy-loaded). One of the lists is inside an overflow-y div (I set the scrollContainer for this) and one is inside a normal div (no scrollContainer set).

The list inside the overflow-y div works, as I scroll inside the div it loads the images. But the list outside which is inside a normal div, weirdly, listens to the scroll events of the first list's scroll container (not window's).

Version: 2.6.5

ezgif-7-c26ec5430412

xmcp commented

+1 on this.

I believe this part of code causes the issue.

function componentDidMount() {
      // ...
      if (this.props.overflow) {
          // add listener to its parent
      } else if (listeners.length === 0 || needResetFinalLazyLoadHandler) {
          // add listener to window
      }

      listeners.push(this);
      // ...
}

So, this issue can be reproduced when:

  • componentDidMount on a <Lazyload> with overflow prop fires first, and then
  • componentDidMount on a <Lazyload> without overflow (i.e. belongs to window) fires after that.

When the first component mounts, it attaches scroll event to its parent, and pushes itself into listeners array.

Then, when the second component mounts, both if (this.props.overflow) and else if (listeners.length === 0 || needResetFinalLazyLoadHandler) check will fail, so no listener is attached on window.

@xmcp can you raise a PR if possible?

I've got the same issue here :) Please submit a PR to fix it, thank you

I've got the same issue here :) Please submit a PR to fix it, thank you

I've studied for whole night and found that this problem seems has been fixed.

add props overflow to your LazyLoad component, likes:
<LazyLoad overflow ... />
maybe fix your problem.

see details at docs overflow.

xmcp commented

I put a reproducible demo on CodeSandbox.

You can see that the LazyLoad without overflow prop is broken until you scroll inside the overflowed div (triggering a visibility check).

I put a reproducible demo on CodeSandbox.

You can see that the LazyLoad without overflow prop is broken until you scroll inside the overflowed div (triggering a visibility check).

my solution is provide scrollContainer and overflow to each scroll instance.
However, the scroll container should set overflow and specify height or position.
(fortunately, specify height to the scroll contrainer is tolerable.)

see CodeSandBox

source
https://codesandbox.io/s/react-lazyload-modal-1p69u?file=/src/App.tsx
view this page with network tab opened to see the actions
https://1p69u.csb.app/

Screen_Shot_2020-08-05_at_10_45_00

I am not sure if I found how to avoid this issue, but adding these props seems to make it work.

For regular <Lazyload/>

  • height

For the <Lazyload/> inside overflow scrolling element

  • height
  • overflow <= !!!

* if you don't give them height they all will be in the initial viewport, so that they all get loaded without scrolling, so giving height is important.