reactjs - 如何使无限滚动获取功能按顺序工作
问题描述
我想无限滚动来获取任何项目,简短的步骤是:
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
无法立即执行。
解决方案
由于您使用的是 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。
推荐阅读
- javascript - 在 JS 中创建动态变量名
- html - 制作类似于 Windows 资源管理器的下拉树形菜单
- kubernetes - 在 istio 中推送目标规则时会发生什么
- testing - Capybara::ElementNotFound 当元素清楚地在页面上时
- c# - 如何通过 Selenium、ChromeDriver 和 GoogleChrome 打开默认 Chrome 配置文件
- sql - Spark Map 数据类型问题
- docker - docker如何为容器中的进程分配内存?
- android - 无法加载 AppCompat ActionBar 并出现未知错误。Android Studio 3.1.3
- reactjs - 如何使用 budo 开发服务器监控链接模块?
- javascript - Javascript ES6 Promise 错误“未捕获(承诺中)”