javascript - 如何通过无限滚动从redux / react中的api逐步获取数据
问题描述
我想通过每次向下滚动来获得 20 个帖子,我该怎么办?我的项目有大数据,我使用 redux 获取数据,我可以一步一步获取数据吗?例如,第一次获得 20 个帖子,当用户向下滚动时加载接下来的 20 个帖子。我使用 React Hooks 进行开发
我的帖子组件来源是:
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import PostItem from './PostItem';
import { getPosts } from '../../actions/post';
const Posts = ({ getPosts, post: { posts, loading } }) => {
useEffect(() => {
getPosts();
}, [getPosts]);
return loading ? <Spinner /> : (
{posts.map(post => (
<PostItem key={post._id} post={post} />
))}
)
}
Posts.propTypes = {
getPosts: PropTypes.func.isRequired,
post: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
post: state.post
});
export default connect(mapStateToProps, { getPosts })(Posts)
我的操作代码是:
import { setAlert } from './alert';
import {
GET_POSTS,
POST_ERROR
} from "../actions/types";
// Get Posts
export const getPosts = () => async dispatch => {
try {
const res = await axios.get('/api/ads');
dispatch({
type: GET_POSTS,
payload: res.data
});
} catch (err) {
dispatch({
type: POST_ERROR,
payload: { msg: err.response.satusText, status: err.response.satus }
});
}
}```
///////////////////////////////
///////////////AND REDUCER IS :
import {
GET_POSTS,
POST_ERROR
} from '../actions/types';
const initialState = {
posts: [],
loading: true,
error: {}
};
export default function (state = initialState, action) {
const { type, payload } = action;
switch (type) {
case GET_POSTS:
return {
...state,
posts: payload,
loading: false
}
case POST_ERROR:
return {
...state,
error: payload,
loading: false
}
default:
return state;
}
}
解决方案
您可以使用react-infinite-scroller库。我试图改变你的Posts
方法,所以也许它会很有用。但正如评论中提到的,你应该在你的 API 中添加分页。
const Posts = ({ getPosts, post: { posts, loading } }) => {
useEffect(() => {
getPosts();
}, [getPosts]);
const itemsPerPage = 20;
const [hasMoreItems, sethasMoreItems] = useState(true);
const [records, setrecords] = useState(itemsPerPage);
const showItems=(posts)=> {
var items = [];
for (var i = 0; i < records; i++) {
items.push( <PostItem key={posts[i]._id} post={posts[i]} />);
}
return items;
}
const loadMore=()=> {
if (records === posts.length) {
sethasMoreItems(false);
} else {
setTimeout(() => {
setrecords(records + itemsPerPage);
}, 2000);
}
}
return <InfiniteScroll
loadMore={loadMore}
hasMore={hasMoreItems}
loader={<div className="loader"> Loading... </div>}
useWindow={false}
>
{showItems()}
</InfiniteScroll>{" "}
}
带有假数据的工作Codesandbox 示例。
推荐阅读
- neo4j - 重构大型密码联合查询
- firebase - “未满足的对等依赖 firebase-admin@6.1.0”
- amazon-web-services - AWS Glue:访问拒绝访问具有 S3 源数据的表
- twine-game-engine - TWINE 游戏本地化
- javascript - 删除@和carret之间的单词
- python - 如何设置从数据库调用数据的时间间隔?[Python]
- python - 遍历所有文本并对项目符号执行某些操作
- java - Hibernate 可以插入但不能删除条目
- c# - 如何确定最小的正可表示浮点值?
- java - PostMapping 的问题 - GetMapping 方法 - 链接中的循环。SpringBoot