调用 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>
  );
}