用几行代码实现无限滚动
介绍
什么是无限滚动?
无限滚动是一种网页设计技术,它会在用户向下滚动页面时持续加载内容,从而消除了分页的需要。
一些使用无限滚动的网站例如:Twitter、9gag等……
我们要构建什么
我不知道它看起来有什么好看的,但你可以改进和设计它,让它看起来更好,这只是一个基本的例子,并介绍一个概念
先决条件
- 本教程假设您具备 React 的工作知识
- 我们将使用React Hooks
- 在开始之前,请确保您的环境中安装了 Node、Yarn 或 npm。
- 当然有网络浏览器
入门
npx create-react-app infiniteScroll
创建完项目文件夹后,您可以通过 cd 进入该文件夹并运行它:
cd infiniteScroll
npm start
这将以开发模式运行应用程序,您可以使用链接http://localhost:3000/在浏览器中查看它。
它看起来会像这样:
组件设置
创建新的无限滚动组件并将以下代码粘贴到其中:
import React, { useState } from 'react';
// styling post container
const divStyle = {
color: 'blue',
height: '250px',
textAlign: 'center',
padding: '5px 10px',
background: '#eee',
marginTop: '15px'
};
// styling container wrapper
const containerStyle = {
maxWidth: '1280px',
margin: '0 auto',
}
const InfiniteScroll = () => {
// initialize list of posts
const [postList, setPostList] = useState({
list: [1,2,3,4]
});
return (<div className="container" style={containerStyle}>
<div className="post-list">
{
postList.list.map((post, index) => {
return (<div key={index}
className="post"
style={divStyle}>
<h2> {post } </h2>
</div>)
})
}
<div className="loading">
<h2>Load More</h2>
</div>
</div>
</div>)
}
export default InfiniteScroll;
您的页面现在看起来如下:
添加无限滚动
为此,我们将使用Interaction Observer API。Intersection
Observer 是一个非常强大的 JavaScript API,它简化了 JavaScript 中基于滚动的事件。Intersection Observer 不会持续检查元素与顶部的距离,而是会监视元素何时进入或退出视口。
我们将使用交互观察器来观察用户何时进入特定点,然后加载更多帖子。
- 首先,我们将从React导入 **useRef * 和useEffect hook,并将它们附加到 Load More div*
- 然后在组件安装时在 Load More div 上注册 IntersectionObserver
- 添加新的状态变量页面,用于跟踪当前页面。为了更真实地模拟示例,我们将如何在连接后端时执行此操作。
- 页面更新的最后一步,只需加载更多帖子
以下是完整的代码:
import React, { useEffect, useState, useRef } from 'react';
const divStyle = {
color: 'blue',
height: '250px',
textAlign: 'center',
padding: '5px 10px',
background: '#eee',
marginTop: '15px'
};
const containerStyle = {
maxWidth: '1280px',
margin: '0 auto',
}
const InfiniteScroll = () => {
const [postList, setPostList] = useState({
list: [1,2,3,4]
});
// tracking on which page we currently are
const [page, setPage] = useState(1);
// add loader refrence
const loader = useRef(null);
useEffect(() => {
var options = {
root: null,
rootMargin: "20px",
threshold: 1.0
};
// initialize IntersectionObserver
// and attaching to Load More div
const observer = new IntersectionObserver(handleObserver, options);
if (loader.current) {
observer.observe(loader.current)
}
}, []);
useEffect(() => {
// here we simulate adding new posts to List
const newList = postList.list.concat([1,1,1,1]);
setPostList({
list: newList
})
}, [page])
// here we handle what happens when user scrolls to Load More div
// in this case we just update page variable
const handleObserver = (entities) => {
const target = entities[0];
if (target.isIntersecting) {
setPage((page) => page + 1)
}
}
return (<div className="container" style={containerStyle}>
<div className="post-list">
{
postList.list.map((post, index) => {
return (<div key={index} className="post" style={divStyle}>
<h2> {post } </h2>
</div>)
})
}
<!-- Add Ref to Load More div -->
<div className="loading" ref={loader}>
<h2>Load More</h2>
</div>
</div>
</div>)
}
export default InfiniteScroll;
这是我在 Dev.to 上的第一篇文章,感谢您的阅读 :)
如果您喜欢这篇文章,您可以通过以下方式找到更多内容:
在 Twitter 上关注我:
文章来源:https://dev.to/hunterjsbit/react-infinite-scroll-in-few-lines-588f