简体   繁体   English

滚动到页面底部 loadMore 被多次调用

[英]Scroll to bottom of the page loadMore gets called more than once

I have a page where a list of profiles are shown and when the user scrolls to the bottom of the page, the query should load more data.我有一个页面,其中显示了配置文件列表,当用户滚动到页面底部时,查询应该加载更多数据。 The loadMore function works as expected but my error is in the listener as when the user scrolls to the bottom quickly, it gets called more than 5 times. loadMore function 按预期工作,但我的错误出现在侦听器中,因为当用户快速滚动到底部时,它被调用了 5 次以上。

const listener = useCallback(() => {
    if (window.innerHeight + window.scrollY >= document.body.scrollHeight) {
      loadMore();
    }
  }, [loadMore]);

  useEffect(() => {
    window.addEventListener('scroll', listener);
    return () => window.removeEventListener('scroll', listener);
  }, [listener]);

This causes the same items in the new query to be shown as it sends the loadMore the same data.这会导致在新查询中显示相同的项目,因为它向 loadMore 发送相同的数据。

When i slowly scroll it works.当我慢慢滚动时,它起作用了。 When I scroll to the bottom fast loads the same profiles 5 different times.当我滚动到底部时,快速加载相同的配置文件 5 次。 Its in the if statement of the listener.它在侦听器的 if 语句中。

Are you using a mac computer?你用的是mac电脑吗? If you scroll to the bottom quickly using the mac mouse, it always stops after the fraction wears out which will keeps triggering the event when the scroll position is in your detect zone.如果您使用 mac 鼠标快速滚动到底部,它总是在分数用完后停止,当滚动 position 处于您的检测区域时,它将继续触发事件。

Use debounce使用去抖动

Here is a good explanation of how to use debounce to prevent quick repeated triggering in your code.这里很好地解释了如何使用 debounce来防止代码中的快速重复触发。

or或者

Use a variable and a timeout使用变量和超时

// Set a variable that indicates the state of pulling profile
var pulling_data = false;

// Ignore if it's true, otherwise et to true when users scroll into your detect zone
if (pulling_data) return;

// An example of fetching data

Ajax({
    before() {
        pulling_data = true;
    }
}).then(res => {
    // Handles data
}).catch(err => {
    // Handles error
}).then(() => {
    let timer_id = setTimeout(() => {
        pulling_data = false;
    }, 1000); // 1 second
});

In above example, no matter how quickly users repeatedly trigger to pull profile data, it always run once and make the next request only available 1 second after the current request is completed.在上面的例子中,无论用户以多快的速度反复触发拉取配置文件数据,它总是运行一次,并且在当前请求完成后 1 秒才使下一个请求可用。 Of course you can change the timer or not to use the timer.当然,您可以更改计时器或不使用计时器。

Use custom event to detect when the scroll is end使用自定义事件来检测滚动何时结束

Here are some examples of creating detecting if the scrolling event ends.以下是创建检测滚动事件是否结束的一些示例 You can trigger your fetch when the event is fired.您可以在触发事件时触发您的获取。

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

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