React-Window-Infinite-Loader预取额外数据

发布于 2025-02-08 21:46:46 字数 3388 浏览 3 评论 0 原文

我不确定为什么会发生这种情况,但是 infiniteloader 在我刚刚加载页面而不滚动时,呼叫两次(从0-8开始,然后从8-16起)全部。另外,即使我在加载16行后只滚动几行滚动,它也会触发另一个电话17-24。

这是我的容器组件

import React from 'react';
import PropTypes from 'prop-types';
import getPropType from '../../../common/js/proptypes';
import { connect } from 'react-redux';
import InfiniteList from 'src/common/components/InfiniteList';
import { fetchNextPage } from '../../state/reducers/training-slice';
import { bindActionCreators } from 'redux';

class Training extends React.Component {
  render() {
    const { hasNextPage, isNextPageLoading, trainings, fetchNextPage } = this.props;
    return (
      <>
        <InfiniteList
          hasNextPage={hasNextPage}
          isNextPageLoading={isNextPageLoading}
          items={trainings}
          loadNextPage={fetchNextPage}
        />
      </>
    );
  }
}

Training.propTypes = {
  trainings: PropTypes.arrayOf(getPropType('training'))
};

const mapState = (state) => {
  console.log(state.trainings);
  return {
    trainings: state.trainings.trainings,
    isNextPageLoading: state.trainings.isFetching,
    hasNextPage: state.trainings.trainings.length % state.trainings.limit === 0
  };
};

const mapDispatch = (dispatch) => bindActionCreators({ fetchNextPage }, dispatch);

export default connect(mapState, mapDispatch)(Training);

。代码>组件

import React from 'react';
import { FixedSizeList as List } from 'react-window';
import InfiniteLoader from 'react-window-infinite-loader';

export default function InfiniteList({ hasNextPage, isNextPageLoading, items, loadNextPage }) {
  // If there are more items to be loaded then add an extra row to hold a loading indicator.
  const itemCount = hasNextPage ? items.length + 1 : items.length;

  const loadMoreItemsProxy = (start, end) => {
    console.log(start, end);
    loadNextPage();
  };
  // Only load 1 page of items at a time.
  // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
  const loadMoreItems = isNextPageLoading ? () => {} : loadMoreItemsProxy;

  // Every row is loaded except for our loading indicator row.
  const isItemLoaded = (index) => !hasNextPage || index < items.length;

  // Render an item or a loading indicator.
  const Item = ({ index, style }) => {
    let content;
    if (!isItemLoaded(index)) {
      content = 'Loading...';
    } else {
      content = items[index].courseFullName;
    }

    return <div style={style}>{content}</div>;
  };

  return (
    <InfiniteLoader
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItemsProxy}
      minimumBatchSize={8}
      threshold={10}
    >
      {({ onItemsRendered, ref }) => (
        <List
          className="List"
          height={150}
          itemCount={itemCount}
          itemSize={30}
          onItemsRendered={onItemsRendered}
          ref={ref}
          width={300}
        >
          {Item}
        </List>
      )}
    </InfiniteLoader>
  );
}

和以下是控制台上状态更改的输出,该输出表明调用两次,以获取16个项目。这里出了什么问题?我尝试了不同的 minimumbatchSize 阈值配置,但似乎不起作用。

I am not sure why this is happening but the InfiniteLoader makes calls to fetch items twice(one for items from 0-8 and then from 8-16) when I am just loading the page and not scrolling at all. Also, even if I scroll only a couple of rows after 16 rows have been loaded, it triggers another call for 17-24.

Here's my container component..pretty similar to their code sandbox example

import React from 'react';
import PropTypes from 'prop-types';
import getPropType from '../../../common/js/proptypes';
import { connect } from 'react-redux';
import InfiniteList from 'src/common/components/InfiniteList';
import { fetchNextPage } from '../../state/reducers/training-slice';
import { bindActionCreators } from 'redux';

class Training extends React.Component {
  render() {
    const { hasNextPage, isNextPageLoading, trainings, fetchNextPage } = this.props;
    return (
      <>
        <InfiniteList
          hasNextPage={hasNextPage}
          isNextPageLoading={isNextPageLoading}
          items={trainings}
          loadNextPage={fetchNextPage}
        />
      </>
    );
  }
}

Training.propTypes = {
  trainings: PropTypes.arrayOf(getPropType('training'))
};

const mapState = (state) => {
  console.log(state.trainings);
  return {
    trainings: state.trainings.trainings,
    isNextPageLoading: state.trainings.isFetching,
    hasNextPage: state.trainings.trainings.length % state.trainings.limit === 0
  };
};

const mapDispatch = (dispatch) => bindActionCreators({ fetchNextPage }, dispatch);

export default connect(mapState, mapDispatch)(Training);

the InfiniteList.js component

import React from 'react';
import { FixedSizeList as List } from 'react-window';
import InfiniteLoader from 'react-window-infinite-loader';

export default function InfiniteList({ hasNextPage, isNextPageLoading, items, loadNextPage }) {
  // If there are more items to be loaded then add an extra row to hold a loading indicator.
  const itemCount = hasNextPage ? items.length + 1 : items.length;

  const loadMoreItemsProxy = (start, end) => {
    console.log(start, end);
    loadNextPage();
  };
  // Only load 1 page of items at a time.
  // Pass an empty callback to InfiniteLoader in case it asks us to load more than once.
  const loadMoreItems = isNextPageLoading ? () => {} : loadMoreItemsProxy;

  // Every row is loaded except for our loading indicator row.
  const isItemLoaded = (index) => !hasNextPage || index < items.length;

  // Render an item or a loading indicator.
  const Item = ({ index, style }) => {
    let content;
    if (!isItemLoaded(index)) {
      content = 'Loading...';
    } else {
      content = items[index].courseFullName;
    }

    return <div style={style}>{content}</div>;
  };

  return (
    <InfiniteLoader
      isItemLoaded={isItemLoaded}
      itemCount={itemCount}
      loadMoreItems={loadMoreItemsProxy}
      minimumBatchSize={8}
      threshold={10}
    >
      {({ onItemsRendered, ref }) => (
        <List
          className="List"
          height={150}
          itemCount={itemCount}
          itemSize={30}
          onItemsRendered={onItemsRendered}
          ref={ref}
          width={300}
        >
          {Item}
        </List>
      )}
    </InfiniteLoader>
  );
}

and following is the output of state changes on the console which shows the call is being made twice to fetch a total of 16 items. what's going wrong here? I have tried different minimumBatchSize and threshold config but it doesn't seem to work.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

哽咽笑 2025-02-15 21:46:46

较低的阈值值似乎阻止了预取。我终于了解了阈值的含义 - 只需将“从底部”添加到文档中的最后一句话。

这意味着,如果您最初加载10个条目,并且具有2个阈值,则LIB将在第8(10-2)条目进入列表的观看口(想想) InterSectionObserver api)

Lower threshold values seem to prevent prefetch. I finally understood what threshold means - Just add "from the bottom" to the last sentence in the doc.

enter image description here

That means if you initially load 10 entries, and have a threshold of 2, the lib will fetch extra data as soon as the 8th(10 - 2) entry is in the viewport of the list(think IntersectionObserver API)

https://codesandbox.io/s/happy-bogdan-rd596c?file=/src/ExampleWrapper.js

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文