调用 api 时,无限滚动在反应中不起作用
Infinite Scrolling not working in the react when api is called
我正在为我的网络应用程序使用 react - redux 环境,但我无法进行无限滚动,到达底部后,我收到无法使用 useEffect 的错误。这是下面的代码:
import React, { useEffect } from 'react';
import './Homefeed.css';
import StickyNav from '../StickyNav/StickyNav';
import { fetchHomePosts } from '../Redux/HomeFeed-Redux/HomeFeedActionMethods';
import { connect } from 'react-redux';
import PostCell from '../PostCell/PostCell';
import InfiniteScroll from 'react-infinite-scroll-component';
import { useDispatch } from 'react-redux'
function Homefeed({homeposts,fetchHomePosts}) {
var skipper = 0;
let dispatch = useDispatch()
useEffect(()=>{fetchHomePosts(skipper);},[dispatch]);
function MorePosts(){
console.log(homeposts);
console.log("more");
useEffect(()=>{fetchHomePosts(skipper+10);},[]);
}
return homeposts.isLoading ? (<h2>Loading...</h2>) : homeposts.error ? (<h3>{homeposts.error}</h3>) : (
<div className="homefeed-layout">
<title>Home Feed</title>
<StickyNav />
<InfiniteScroll
dataLength={homeposts.homeposts.length}
hasMore={true}
loader={<h3>Loading</h3>}
next={()=>{MorePosts()}}
>
{
homeposts.homeposts?.map((key,index)=> {
var slug = key.attributes.title;
slug = slug.replace(/\s/g, '-');
slug = slug.toLowerCase();
slug = slug.replace(/[^a-zA-Z0-9\-]/g, '');
slug = slug.replace(/(-)+/g, '-');
slug = slug.replace(/-$/, '');
slug = slug.replace(/^-/, '');
return(
<div className="content-area" key={index} >
<PostCell
key ={index}
slug = {slug}
postId = {key.id}
title ={key.attributes.title}
likes ={key.attributes.likes}
comments ={key.attributes.comments}
category ={key.attributes.category}
postimageurl = {key.attributes.postImageURL}
handle ={key.attributes.createdBy.attributes.handle}
timestamp = {key.attributes.createdAt}
subtitle = {key.attributes.subtitle}
realName ={key.attributes.createdBy.attributes.realName}
profileImage = {key.attributes.createdBy.attributes.profileImage?._url}
followers = {key.attributes.createdBy.attributes.followers}
posts = {key.attributes.createdBy.attributes.posts}
name = {key.attributes.createdBy.attributes.name}
/>
</div>
)
})
}
</InfiniteScroll>
</div>
)
}
const mapStatetoProps = (state) =>{
return{
homeposts:state.HomePosts
}
}
const mapDispatchtoProps = (dispatch) =>{
return{
fetchHomePosts:(skipper)=>{dispatch(fetchHomePosts(skipper))},dispatch,
}
}
export default connect(mapStatetoProps,mapDispatchtoProps) (Homefeed)
所以无限滚动中的下一个道具应该调用更多数据,这些数据应该附加到现有数据。 moreposts 函数应该调用 api 但反应给了我一个错误,说你不能在这个函数中调用 useEffect。
如果我使用 useDispatch(),它会陷入无限循环,有人可以帮助我吗,我对此很陌生。
您不能在另一个函数内部调用 useEffect
,因为这违反了挂钩规则。但是 useEffect
在这里没有做任何事情。您可以从 morePosts()
.
调用 fetchHomePosts(skipper+10)
这将加载第二页。如果你想加载第三个和第四个等等,那么你需要使 skipper
成为一个状态而不是 var
。每次加载页面时将 10
添加到 skipper
。
您可以:
- 递增
skipper
并在 morePosts()
函数中调用 fetchHomePosts()
。
- 在您的
morePosts()
函数中增加 skipper
并从 useEffect
挂钩调用 fetchHomePosts()
,该挂钩具有 skipper
作为依赖项,以便效果在任何时候运行skipper
的值发生变化。
- 将最后获取的页码保存在您的 Redux 商店中。
- 偏移量基于
homePosts
数组的长度。
您不需要使用 useDispatch
和 connect
。它们是做同一件事的两种方法,因此您应该使用其中一种。钩子是推荐的方法。
这并不完美,但我不想让事情过于复杂:
export default function Homefeed() {
const homeposts = useSelector((state) => state.HomePosts);
const dispatch = useDispatch();
// want to make sure that the first page is loaded when the component mounts
useEffect(() => {
dispatch(fetchHomePosts(0));
}, [dispatch]);
// starts at 0 and increases when more posts load
const dataLength = homeposts.homeposts.length;
// function to load the next page
const morePosts = () => {
dispatch(fetchHomePosts(dataLength));
};
return homeposts.isLoading ? (
<h2>Loading...</h2>
) : homeposts.error ? (
<h3>{homeposts.error}</h3>
) : (
<div className="homefeed-layout">
<title>Home Feed</title>
<StickyNav />
<InfiniteScroll
dataLength={dataLength}
hasMore={true}
loader={<h3>Loading</h3>}
next={morePosts}
>
{homeposts.homeposts?.map((key, index) => {
// I would store this slug in Redux when you store the post
const slug = key.attributes.title
.replace(/\s/g, "-")
.toLowerCase()
.replace(/[^a-zA-Z0-9-]/g, "")
.replace(/(-)+/g, "-")
.replace(/-$/, "")
.replace(/^-/, "");
return (
<div className="content-area" key={index}>
<PostCell
key={index}
slug={slug}
postId={key.id}
title={key.attributes.title}
likes={key.attributes.likes}
comments={key.attributes.comments}
category={key.attributes.category}
postimageurl={key.attributes.postImageURL}
handle={key.attributes.createdBy.attributes.handle}
timestamp={key.attributes.createdAt}
subtitle={key.attributes.subtitle}
realName={key.attributes.createdBy.attributes.realName}
profileImage={
key.attributes.createdBy.attributes.profileImage?._url
}
followers={key.attributes.createdBy.attributes.followers}
posts={key.attributes.createdBy.attributes.posts}
name={key.attributes.createdBy.attributes.name}
/>
</div>
);
})}
</InfiniteScroll>
</div>
);
}
我正在为我的网络应用程序使用 react - redux 环境,但我无法进行无限滚动,到达底部后,我收到无法使用 useEffect 的错误。这是下面的代码:
import React, { useEffect } from 'react';
import './Homefeed.css';
import StickyNav from '../StickyNav/StickyNav';
import { fetchHomePosts } from '../Redux/HomeFeed-Redux/HomeFeedActionMethods';
import { connect } from 'react-redux';
import PostCell from '../PostCell/PostCell';
import InfiniteScroll from 'react-infinite-scroll-component';
import { useDispatch } from 'react-redux'
function Homefeed({homeposts,fetchHomePosts}) {
var skipper = 0;
let dispatch = useDispatch()
useEffect(()=>{fetchHomePosts(skipper);},[dispatch]);
function MorePosts(){
console.log(homeposts);
console.log("more");
useEffect(()=>{fetchHomePosts(skipper+10);},[]);
}
return homeposts.isLoading ? (<h2>Loading...</h2>) : homeposts.error ? (<h3>{homeposts.error}</h3>) : (
<div className="homefeed-layout">
<title>Home Feed</title>
<StickyNav />
<InfiniteScroll
dataLength={homeposts.homeposts.length}
hasMore={true}
loader={<h3>Loading</h3>}
next={()=>{MorePosts()}}
>
{
homeposts.homeposts?.map((key,index)=> {
var slug = key.attributes.title;
slug = slug.replace(/\s/g, '-');
slug = slug.toLowerCase();
slug = slug.replace(/[^a-zA-Z0-9\-]/g, '');
slug = slug.replace(/(-)+/g, '-');
slug = slug.replace(/-$/, '');
slug = slug.replace(/^-/, '');
return(
<div className="content-area" key={index} >
<PostCell
key ={index}
slug = {slug}
postId = {key.id}
title ={key.attributes.title}
likes ={key.attributes.likes}
comments ={key.attributes.comments}
category ={key.attributes.category}
postimageurl = {key.attributes.postImageURL}
handle ={key.attributes.createdBy.attributes.handle}
timestamp = {key.attributes.createdAt}
subtitle = {key.attributes.subtitle}
realName ={key.attributes.createdBy.attributes.realName}
profileImage = {key.attributes.createdBy.attributes.profileImage?._url}
followers = {key.attributes.createdBy.attributes.followers}
posts = {key.attributes.createdBy.attributes.posts}
name = {key.attributes.createdBy.attributes.name}
/>
</div>
)
})
}
</InfiniteScroll>
</div>
)
}
const mapStatetoProps = (state) =>{
return{
homeposts:state.HomePosts
}
}
const mapDispatchtoProps = (dispatch) =>{
return{
fetchHomePosts:(skipper)=>{dispatch(fetchHomePosts(skipper))},dispatch,
}
}
export default connect(mapStatetoProps,mapDispatchtoProps) (Homefeed)
所以无限滚动中的下一个道具应该调用更多数据,这些数据应该附加到现有数据。 moreposts 函数应该调用 api 但反应给了我一个错误,说你不能在这个函数中调用 useEffect。
如果我使用 useDispatch(),它会陷入无限循环,有人可以帮助我吗,我对此很陌生。
您不能在另一个函数内部调用 useEffect
,因为这违反了挂钩规则。但是 useEffect
在这里没有做任何事情。您可以从 morePosts()
.
fetchHomePosts(skipper+10)
这将加载第二页。如果你想加载第三个和第四个等等,那么你需要使 skipper
成为一个状态而不是 var
。每次加载页面时将 10
添加到 skipper
。
您可以:
- 递增
skipper
并在morePosts()
函数中调用fetchHomePosts()
。 - 在您的
morePosts()
函数中增加skipper
并从useEffect
挂钩调用fetchHomePosts()
,该挂钩具有skipper
作为依赖项,以便效果在任何时候运行skipper
的值发生变化。 - 将最后获取的页码保存在您的 Redux 商店中。
- 偏移量基于
homePosts
数组的长度。
您不需要使用 useDispatch
和 connect
。它们是做同一件事的两种方法,因此您应该使用其中一种。钩子是推荐的方法。
这并不完美,但我不想让事情过于复杂:
export default function Homefeed() {
const homeposts = useSelector((state) => state.HomePosts);
const dispatch = useDispatch();
// want to make sure that the first page is loaded when the component mounts
useEffect(() => {
dispatch(fetchHomePosts(0));
}, [dispatch]);
// starts at 0 and increases when more posts load
const dataLength = homeposts.homeposts.length;
// function to load the next page
const morePosts = () => {
dispatch(fetchHomePosts(dataLength));
};
return homeposts.isLoading ? (
<h2>Loading...</h2>
) : homeposts.error ? (
<h3>{homeposts.error}</h3>
) : (
<div className="homefeed-layout">
<title>Home Feed</title>
<StickyNav />
<InfiniteScroll
dataLength={dataLength}
hasMore={true}
loader={<h3>Loading</h3>}
next={morePosts}
>
{homeposts.homeposts?.map((key, index) => {
// I would store this slug in Redux when you store the post
const slug = key.attributes.title
.replace(/\s/g, "-")
.toLowerCase()
.replace(/[^a-zA-Z0-9-]/g, "")
.replace(/(-)+/g, "-")
.replace(/-$/, "")
.replace(/^-/, "");
return (
<div className="content-area" key={index}>
<PostCell
key={index}
slug={slug}
postId={key.id}
title={key.attributes.title}
likes={key.attributes.likes}
comments={key.attributes.comments}
category={key.attributes.category}
postimageurl={key.attributes.postImageURL}
handle={key.attributes.createdBy.attributes.handle}
timestamp={key.attributes.createdAt}
subtitle={key.attributes.subtitle}
realName={key.attributes.createdBy.attributes.realName}
profileImage={
key.attributes.createdBy.attributes.profileImage?._url
}
followers={key.attributes.createdBy.attributes.followers}
posts={key.attributes.createdBy.attributes.posts}
name={key.attributes.createdBy.attributes.name}
/>
</div>
);
})}
</InfiniteScroll>
</div>
);
}