0

我想无限滚动来获取任何项目,简短的步骤是:

1) 在屏幕末尾滚动。

2)使用redux更新items pageIndex。

3) 用于componentDidUpdate捕捉这个 redux 动作。

4) 将获取的项目附加到项目数组的末尾。

class InfiniteScroll extends React.Component {
  componentDidMount() {
    window.addEventListener("scroll", throttle(this.onScroll, 500), false);
  }
  componentWillUnmount() {
    window.removeEventListener("scroll", this.onScroll, false);
  }
  componentDidUpdate(preProps) {
    if (props.pageindex === preProps.pageindex + 1)
      fetchItems(...);
  }
  onScroll = () => {
    if (
      window.innerHeight + window.scrollY >=
      document.body.offsetHeight - 100
    ) {
      updatePage(...);
    }
  };
  render() {
    return <Component {...this.props} />;
  }
}

此代码的唯一问题是updatePage执行一次时,fetchItems无法立即执行。

4

2 回答 2

2

由于您使用的是 redux,因此您的项目列表应通过操作/reducer 进行控制。

InfiniteScroll.js:

onScroll () {
    var nearBottom = window.innerHeight + window.scrollY >= document.body.offsetHeight - 100;
    if (!this.props.fetching && nearBottom) {
        fetchItems();  // dispatch action
    }
}

render () {
    var items = this.props.items.map(item => (<Component {item}/>)

    return (
        <ul>{ items }</ul>
    )
}

componentDidMount() {
    window.addEventListener("scroll", this.onScroll.bind(this), false);
}
componentWillUnmount() {
    window.removeEventListener("scroll", this.onScroll.bind(this), false);
}

行动:

fetchItems () {
    return dispatch => {
        dispatch({
            type: "FETCH_ITEMS"
        });
        fetch("/api/items")
        .then(items => {
            dispatch(itemsReceived(items));
        });
    }
}
itemsReceived (items) {
    return {
        type: "ITEMS_RECEIVED",
        payload: {
            items: items
        }
    }
}

减速器:

case "FETCH_ITEMS":
    return {
        ...prevState,
        fetching: true

case "ITEMS_RECEIVED":
    return {
        ...prevState,
        fetching: false,
        items: prevState.items.concat(items)
    }

这样,滚动触发了明确定义的操作(FETCH_ITEMS)。使用redux-thunk,该操作进行 API 调用以获取新项目。当该调用完成时,您将调度一个新操作以通过 reducer 提供新项目。

然后 reducer 更新状态,导致<InfiniteScroll>使用更新的项目列表重新渲染。

注意:如果出现错误,您还应该将 fetching 设置为 false。

于 2018-07-13T18:01:14.410 回答
1

如果我是你,我会使用图书馆为我做繁重的工作。

一种选择是react-infinite-scroller

以下是您的用例的样子,主要是伪代码:

<InfiniteScroll
    pageStart={0}
    loadMore={fetchItems} // that's your method for loading more results
    hasMore={props.pageindex === preProps.pageindex + 1} // your 'has more' logic
    loader={<div className="loader">Loading ...</div>}
>
    {items} // <-- This is the content you want to load
</InfiniteScroll>

对于一个工作示例,请查看他们的 repo 中的演示


另一种选择是尝试调试您的代码。但是您需要提供更多上下文。从您提供的信息中,很难判断出什么问题。

于 2018-07-13T17:30:06.660 回答