【问题标题】:Infinite Scroll with react and api calls updating state带有反应和 api 调用更新状态的无限滚动
【发布时间】:2020-02-08 19:32:53
【问题描述】:

我正在尝试使用 vanilla javascript 获取无限滚动教程并使用 react。为了更好地理解反应是如何工作的。我可以获取数据显示初始数据。滚动到底部获取更多数据,但数据刚好超过当前数据。此外,如果有人能指出我正确的方向,我只能翻到第 2 页。

import React, { useState, useEffect } from "react";

import "./App.css";

function App() {
  const [posts, setPosts] = useState([{}]);
  const [isFetching, setIsFetching] = useState(false);
  let limit = 5;
  let page = 1;

  const getPosts = async () => {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`
    );
    const data = await response.json();
    setPosts(data);
    console.log(data);
  };

  function handleScroll() {
    if (
      window.innerHeight + document.documentElement.scrollTop !==
      document.documentElement.offsetHeight
    )
      return;
    setIsFetching(true);
  }

  function getMorePosts() {
    setTimeout(() => {
      page++;
      setPosts([{ ...posts }], posts);
      setIsFetching(false);
    }, 2000);
  }

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => window.removeEventListener("scroll", handleScroll);
  }, []);

  useEffect(
    () => {
      getPosts();
    }, //eslint-disable-next-line
    []
  );
  useEffect(() => {
    if (!isFetching) return;
    getMorePosts();
  }, [isFetching]);

  return (
    <div className="App">
      {posts.map((post, index) => (
        <div key={index} className="post">
          <div className="number">{post.id}</div>
          <div className="post-info">
            <h2 className="post-title">{post.title}</h2>
            <p className="post-body">{post.body}</p>
          </div>
        </div>
      ))}
      {isFetching && (
        <div className="loader">
          <div className="circle"></div>
          <div className="circle"></div>
          <div className="circle"></div>
        </div>
      )}
    </div>
  );
}

export default App;

【问题讨论】:

    标签: javascript reactjs state react-hooks


    【解决方案1】:

    我注意到的一件事是page 不在状态,因此它将在每次渲染时重置。此外,由于limit 没有改变,您应该使用一个常量。

    为什么要将它初始化为一个包含空对象的数组? useState([{}]); 只使用一个空数组

    另外我不确定你打算在这里做什么setPosts([{ ...posts }], posts);,但如果你想在复制对象时附加新帖子,你应该这样做

      const getPosts = async () => {
        setIsFetching(true)
        const response = await fetch(
          `https://jsonplaceholder.typicode.com/posts?_limit=${limit}&_page=${page}`
        );
        const data = await response.json();
        setPosts([...posts, ...data]);
        setIsFetching(false)
      };
    
      function getMorePosts() {
        setTimeout(() => {
          setPage(page++)
          getPosts();
        }, 2000);
      }
    

    【讨论】:

    • 谢谢你说得通!我想如果我得到的数据是一个对象数组,我需要以这种方式初始化它。
    • NP 你能选择我的答案吗:)
    猜你喜欢
    • 2020-07-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2018-12-08
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多