Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在无限滚动中超过最大更新深度_Javascript_Node.js_Reactjs_Infinite Scroll - Fatal编程技术网

Javascript 在无限滚动中超过最大更新深度

Javascript 在无限滚动中超过最大更新深度,javascript,node.js,reactjs,infinite-scroll,Javascript,Node.js,Reactjs,Infinite Scroll,我正在尝试在MERN stack应用程序中实现延迟加载,如中所示。我希望默认显示在当前日期创建的帖子。如果用户向下滚动,它将在上一个日期获取更多数据。我用的是无限卷轴。然而,似乎应用程序对api的请求就像一个无限循环,而不监听滚动。我犯了以下错误。 超出了最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这个函数是async/await,所以我不明白为什

我正在尝试在MERN stack应用程序中实现延迟加载,如中所示。我希望默认显示在当前日期创建的帖子。如果用户向下滚动,它将在上一个日期获取更多数据。我用的是无限卷轴。然而,似乎应用程序对api的请求就像一个无限循环,而不监听滚动。我犯了以下错误。 超出了最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。

这个函数是async/await,所以我不明白为什么它一直在调用新的请求,即使旧的请求还没有被解析

在一个Post组件中

import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import PostItem from './PostItem';
import UserItem from '../users/UserItem';
import TopDiscussion from '../TopDiscussion';
import SmallAbout from '../SmallAbout';
import { getPostsByDate } from '../../actions/post';
import Moment from 'react-moment';
import InfiniteScroll from 'react-infinite-scroller';

const Posts = ({ getPostsByDate, post: { posts, loading } }) => {
  const now = new Date();
  const startOfToday = new Date(
    now.getFullYear(),
    now.getMonth(),
    now.getDate()
  );

  // startOfToday =  startOfToday -1
  useEffect(() => {
    getPostsByDate(startOfToday);
  }, [getPostsByDate]);

  const [date, setDate] = useState(startOfToday);
  const [shown, setShown] = useState();

  const getPosts = () => {
    getPostsByDate(date);
    let count = new Date(date);
    count.setDate(count.getDate() - 1);
    setDate(count);
  };

  return loading ? (
    <Spinner />
  ) : (
    <div className='main-grid'>
      <div className='posts-grid'>
        <h1 className='large text-primary'>Ideas</h1>
        <div className='posts'>
          <div className='post-dummy'>
            <InfiniteScroll
              dataLength={posts.length}
              pageStart={0}
              loadMore={getPosts}
              hasMore={posts && posts.length < 10}
              loader={
                <div className='loader' key={0}>
                  Loading ...
                </div>
              }
            >
              {posts
                .sort((a, b) =>
                  a.likes.length > b.likes.length
                    ? -1
                    : b.likes.length > a.likes.length
                    ? 1
                    : 0
                )
                .map(post => (
                  <PostItem key={post._id} post={post} />
                ))}
            </InfiniteScroll>
          </div>
        </div>
      </div>
      <div className='right-panel-grid'>
        <SmallAbout />
        <UserItem />
        <TopDiscussion posts={posts} />
        <div
          className='fb-group'
          data-href='https://www.facebook.com/groups/ideatoshare/'
          data-width='350'
          data-show-social-context='true'
          data-show-metadata='false'
        ></div>

        <iframe
          title='producthunt'
          style={{ border: 'none' }}
          src='https://cards.producthunt.com/cards/posts/168618?v=1'
          width='350'
          height='405'
          frameBorder='0'
          scrolling='no'
          allowFullScreen
        ></iframe>
      </div>
    </div>
  );
};

Posts.propTypes = {
  getPostsByDate: PropTypes.func.isRequired,
  post: PropTypes.object.isRequired
};

const mapStateToProps = state => ({
  post: state.post
});
export default connect(
  mapStateToProps,
  { getPostsByDate }
)(Posts);

事后行动

//GetTodayPost
export const getPostsByDate = date => async dispatch => {
  try {
    const res = await axios.get(`/api/posts/${date}`);
    dispatch({
      type: GET_POSTS,
      payload: res.data
    });
  } catch (err) {
    dispatch({
      type: POST_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};
后API

router.get('/:date', async (req, res) => {
  try {

    const startOfToday = new Date(req.params.date);
    const endOfToday = new Date(req.params.date);
    endOfToday.setDate(endOfToday.getDate() + 1);
    const posts = await Post.find({
      date: { $gte: startOfToday, $lte: endOfToday }
    }).sort({
      date: -1
    });
    res.json(posts);
  } catch (err) {
    console.error(err.message);
    res.send(500).send('Server Error');
  }
});


编辑:我已用..更新了您的回购协议。。你的问题是,你的API并不像你声称的那样是“无限制的”,你实际上需要检查是否所有帖子都已加载。。使用我提供的示例以及我对您的回购协议所做的更新,您应该能够从这里了解情况

好的。。因此,在使用
InfiniteScroll
进行一些测试之后,这似乎发生了,因为您的
hasMore
属性始终等于
true
。。。您必须指定某种类型的条件,以便
InfiniteScroll
知道何时加载更多数据,何时不加载更多数据

在添加检查之前,我遇到了与您相同的错误,它告诉
InfiniteSroll
没有更多的数据要加载

我构建了以下示例来演示如何使用
InfiniteScroll


PostsContainer.js

import React, { useState, useEffect } from "react";
import Posts from "./Posts";
import InfiniteScroll from "react-infinite-scroller";

const loadingStyle = {
  textAlign: "center",
  fontSize: "48px",
  color: "red"
};

function PostsContainer({ url, itemsToDisplay = 5 }) {
  const [data, setData] = useState();
  const [shownData, setShownData] = useState();

  useEffect(() => {
    (async () => {
      let items = await fetchPosts(url);
      let itemsToShow = selectNItems(items, itemsToDisplay);
      setShownData(itemsToShow);
      setData(items);
    })();
  }, [url]);

  async function fetchPosts(url) {
    let res = await fetch(url);
    return await res.json();
  }

  const selectNItems = (obj, n) => {
    return obj.slice(0, n);
  }

  const loadMorePosts = () => {
    let items =
      data &&
      shownData && 
      selectNItems(data, shownData.length + itemsToDisplay)
    setShownData(items);
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMorePosts}
      hasMore={data && shownData && data.length > shownData.length}
      loader={<div style={loadingStyle}>Loading ...</div>}
      useWindow={true}
    >
      <Posts posts={shownData} />
    </InfiniteScroll>
  );
}

export default PostsContainer;
import React from 'react';
import Post from './Post';

const headingStyle = {
  textAlign: 'center',
}

function Posts({ posts }) {
  return(
    <div>
      <h1 style={headingStyle}>Posts</h1>
      {posts && posts.length > 0 && posts.map((p, i) => <Post key={i} data={p} index={i} />)}
    </div>
  );
}

export default Posts;
import React from "react";

const containerStyle = {
  border: "1px solid black",
  margin: "10px auto",
  maxWidth: "50vw",
  padding: '0px 10px 0px 0px'
};

const postHeaderStyle = {
  textAlign: "center",
  padding: "0px"
};

function Post({ data, index }) {
  return (
    <div style={containerStyle}>
      {index !== "" && <h3 style={postHeaderStyle}>Post #{index}</h3>}
      <ul>
        <li>
          <b>userId:</b> {data.userId}
        </li>
        <li>
          <b>id:</b> {data.id}
        </li>
        <li>
          <b>title:</b> {data.title}
        </li>
        <li>
          <b>body:</b> {data.body}
        </li>
      </ul>
    </div>
  );
}

export default Post;
import React from "react";
import { render } from "react-dom";
import PostsContainer from "./Components/PostsContainer";

function App() {
  return (
    <PostsContainer
      itemsToDisplay={5}
      url="https://jsonplaceholder.typicode.com/posts"
    />
  );
}

render(<App />, document.getElementById("root"));
import React,{useState,useffect}来自“React”;
从“/Posts”导入帖子;
从“反应无限滚动条”导入无限滚动条;
常量加载方式={
textAlign:“居中”,
字体大小:“48px”,
颜色:“红色”
};
函数PostsContainer({url,itemsToDisplay=5}){
const[data,setData]=useState();
const[shownData,setShownData]=useState();
useffect(()=>{
(异步()=>{
let items=等待获取帖子(url);
let itemsToShow=选择项(items,itemsToDisplay);
设置显示数据(项目显示);
设置数据(项目);
})();
},[url]);
异步函数fetchPosts(url){
let res=等待获取(url);
return wait res.json();
}
const selectNItems=(对象,n)=>{
返回对象切片(0,n);
}
const loadMorePosts=()=>{
让项目=
资料&&
shownada&
选择项目(数据,显示数据长度+项目显示)
设置显示数据(项目);
};
返回(
shownData.length}
加载器={正在加载…}
useWindow={true}
>
);
}
导出默认PostsContainer;

Posts.js

import React, { useState, useEffect } from "react";
import Posts from "./Posts";
import InfiniteScroll from "react-infinite-scroller";

const loadingStyle = {
  textAlign: "center",
  fontSize: "48px",
  color: "red"
};

function PostsContainer({ url, itemsToDisplay = 5 }) {
  const [data, setData] = useState();
  const [shownData, setShownData] = useState();

  useEffect(() => {
    (async () => {
      let items = await fetchPosts(url);
      let itemsToShow = selectNItems(items, itemsToDisplay);
      setShownData(itemsToShow);
      setData(items);
    })();
  }, [url]);

  async function fetchPosts(url) {
    let res = await fetch(url);
    return await res.json();
  }

  const selectNItems = (obj, n) => {
    return obj.slice(0, n);
  }

  const loadMorePosts = () => {
    let items =
      data &&
      shownData && 
      selectNItems(data, shownData.length + itemsToDisplay)
    setShownData(items);
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMorePosts}
      hasMore={data && shownData && data.length > shownData.length}
      loader={<div style={loadingStyle}>Loading ...</div>}
      useWindow={true}
    >
      <Posts posts={shownData} />
    </InfiniteScroll>
  );
}

export default PostsContainer;
import React from 'react';
import Post from './Post';

const headingStyle = {
  textAlign: 'center',
}

function Posts({ posts }) {
  return(
    <div>
      <h1 style={headingStyle}>Posts</h1>
      {posts && posts.length > 0 && posts.map((p, i) => <Post key={i} data={p} index={i} />)}
    </div>
  );
}

export default Posts;
import React from "react";

const containerStyle = {
  border: "1px solid black",
  margin: "10px auto",
  maxWidth: "50vw",
  padding: '0px 10px 0px 0px'
};

const postHeaderStyle = {
  textAlign: "center",
  padding: "0px"
};

function Post({ data, index }) {
  return (
    <div style={containerStyle}>
      {index !== "" && <h3 style={postHeaderStyle}>Post #{index}</h3>}
      <ul>
        <li>
          <b>userId:</b> {data.userId}
        </li>
        <li>
          <b>id:</b> {data.id}
        </li>
        <li>
          <b>title:</b> {data.title}
        </li>
        <li>
          <b>body:</b> {data.body}
        </li>
      </ul>
    </div>
  );
}

export default Post;
import React from "react";
import { render } from "react-dom";
import PostsContainer from "./Components/PostsContainer";

function App() {
  return (
    <PostsContainer
      itemsToDisplay={5}
      url="https://jsonplaceholder.typicode.com/posts"
    />
  );
}

render(<App />, document.getElementById("root"));
从“React”导入React;
从“./Post”导入Post;
常数头样式={
textAlign:'中心',
}
职能职位({Posts}){
返回(
帖子
{posts&&posts.length>0&&posts.map((p,i)=>)}
);
}
导出默认职位;

Post.js

import React, { useState, useEffect } from "react";
import Posts from "./Posts";
import InfiniteScroll from "react-infinite-scroller";

const loadingStyle = {
  textAlign: "center",
  fontSize: "48px",
  color: "red"
};

function PostsContainer({ url, itemsToDisplay = 5 }) {
  const [data, setData] = useState();
  const [shownData, setShownData] = useState();

  useEffect(() => {
    (async () => {
      let items = await fetchPosts(url);
      let itemsToShow = selectNItems(items, itemsToDisplay);
      setShownData(itemsToShow);
      setData(items);
    })();
  }, [url]);

  async function fetchPosts(url) {
    let res = await fetch(url);
    return await res.json();
  }

  const selectNItems = (obj, n) => {
    return obj.slice(0, n);
  }

  const loadMorePosts = () => {
    let items =
      data &&
      shownData && 
      selectNItems(data, shownData.length + itemsToDisplay)
    setShownData(items);
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMorePosts}
      hasMore={data && shownData && data.length > shownData.length}
      loader={<div style={loadingStyle}>Loading ...</div>}
      useWindow={true}
    >
      <Posts posts={shownData} />
    </InfiniteScroll>
  );
}

export default PostsContainer;
import React from 'react';
import Post from './Post';

const headingStyle = {
  textAlign: 'center',
}

function Posts({ posts }) {
  return(
    <div>
      <h1 style={headingStyle}>Posts</h1>
      {posts && posts.length > 0 && posts.map((p, i) => <Post key={i} data={p} index={i} />)}
    </div>
  );
}

export default Posts;
import React from "react";

const containerStyle = {
  border: "1px solid black",
  margin: "10px auto",
  maxWidth: "50vw",
  padding: '0px 10px 0px 0px'
};

const postHeaderStyle = {
  textAlign: "center",
  padding: "0px"
};

function Post({ data, index }) {
  return (
    <div style={containerStyle}>
      {index !== "" && <h3 style={postHeaderStyle}>Post #{index}</h3>}
      <ul>
        <li>
          <b>userId:</b> {data.userId}
        </li>
        <li>
          <b>id:</b> {data.id}
        </li>
        <li>
          <b>title:</b> {data.title}
        </li>
        <li>
          <b>body:</b> {data.body}
        </li>
      </ul>
    </div>
  );
}

export default Post;
import React from "react";
import { render } from "react-dom";
import PostsContainer from "./Components/PostsContainer";

function App() {
  return (
    <PostsContainer
      itemsToDisplay={5}
      url="https://jsonplaceholder.typicode.com/posts"
    />
  );
}

render(<App />, document.getElementById("root"));
从“React”导入React;
常量集装箱样式={
边框:“1px纯黑”,
边距:“10px自动”,
最大宽度:“50vw”,
填充:“0px 10px 0px 0px”
};
const postHeaderStyle={
textAlign:“居中”,
填充:“0px”
};
函数Post({data,index}){
返回(
{index!=''&&Post{index}
  • userId:{data.userId}
  • id:{data.id}
  • 标题:{data.title}
  • 正文:{data.body}
); } 导出默认帖子;

index.js

import React, { useState, useEffect } from "react";
import Posts from "./Posts";
import InfiniteScroll from "react-infinite-scroller";

const loadingStyle = {
  textAlign: "center",
  fontSize: "48px",
  color: "red"
};

function PostsContainer({ url, itemsToDisplay = 5 }) {
  const [data, setData] = useState();
  const [shownData, setShownData] = useState();

  useEffect(() => {
    (async () => {
      let items = await fetchPosts(url);
      let itemsToShow = selectNItems(items, itemsToDisplay);
      setShownData(itemsToShow);
      setData(items);
    })();
  }, [url]);

  async function fetchPosts(url) {
    let res = await fetch(url);
    return await res.json();
  }

  const selectNItems = (obj, n) => {
    return obj.slice(0, n);
  }

  const loadMorePosts = () => {
    let items =
      data &&
      shownData && 
      selectNItems(data, shownData.length + itemsToDisplay)
    setShownData(items);
  };

  return (
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMorePosts}
      hasMore={data && shownData && data.length > shownData.length}
      loader={<div style={loadingStyle}>Loading ...</div>}
      useWindow={true}
    >
      <Posts posts={shownData} />
    </InfiniteScroll>
  );
}

export default PostsContainer;
import React from 'react';
import Post from './Post';

const headingStyle = {
  textAlign: 'center',
}

function Posts({ posts }) {
  return(
    <div>
      <h1 style={headingStyle}>Posts</h1>
      {posts && posts.length > 0 && posts.map((p, i) => <Post key={i} data={p} index={i} />)}
    </div>
  );
}

export default Posts;
import React from "react";

const containerStyle = {
  border: "1px solid black",
  margin: "10px auto",
  maxWidth: "50vw",
  padding: '0px 10px 0px 0px'
};

const postHeaderStyle = {
  textAlign: "center",
  padding: "0px"
};

function Post({ data, index }) {
  return (
    <div style={containerStyle}>
      {index !== "" && <h3 style={postHeaderStyle}>Post #{index}</h3>}
      <ul>
        <li>
          <b>userId:</b> {data.userId}
        </li>
        <li>
          <b>id:</b> {data.id}
        </li>
        <li>
          <b>title:</b> {data.title}
        </li>
        <li>
          <b>body:</b> {data.body}
        </li>
      </ul>
    </div>
  );
}

export default Post;
import React from "react";
import { render } from "react-dom";
import PostsContainer from "./Components/PostsContainer";

function App() {
  return (
    <PostsContainer
      itemsToDisplay={5}
      url="https://jsonplaceholder.typicode.com/posts"
    />
  );
}

render(<App />, document.getElementById("root"));
从“React”导入React;
从“react dom”导入{render};
从“/Components/PostsContainer”导入PostsContainer;
函数App(){
返回(
);
}
render(,document.getElementById(“根”));

您是在为InfiniteScroll元素使用npm包,还是自定义的?无论哪种方式,如何实现
loadMore
?您使用的是哪个InfiniteScroll软件包?我猜这是因为您在
getPosts
中调用
getPostByDate
,并且
getPostByDate
被列为
useffect
的依赖项数组。。如果将
useffect
中的
[getPostByDate]
更改为just
[]
是否仍会发生这种情况?对于那些想知道正在使用的软件包的人,您将不得不分享更多的代码和redux设置,以供任何人帮助。你能用整个
Posts
组件和一些redux代码更新你的帖子吗?听起来这个问题与您没有跟踪当前显示的项目数量与项目总数有关。如果您查看上面我的
PostsContainer
组件,它显示了您必须如何跟踪总项目以及显示的项目…我想这一切都取决于您是否知道您使用的API是否有限制。。例如,我知道我使用的API只有100篇文章。。我更新了StackBlitz演示,展示了如何使用Redux实现这一点,以及如何在
loadMore
期间调用API。。我即将崩溃,但明天我将用一些Redux代码和StackBlitz更新的组件更新我的答案。。显然,您希望PostsContainer更灵活一些,但我只是想向您展示一下目前如何实现这一点。您使用的是什么API?它是公开的吗?我在任何地方都没有看到它。哦,好吧,祝你好运把这个修好!