Бесконечная прокрутка с обновлением состояния реакции и API-вызовов - PullRequest
0 голосов
/ 08 февраля 2020

Я пытаюсь взять урок для бесконечного свитка с использованием ванили javascript и использую реагирование. Чтобы лучше понять, как работает реакция. Я могу получить данные отображения начальных данных. Прокрутите до нижней части, чтобы получить больше данных, но данные только по текущим данным. Также я могу получить только до страницы 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;

1 Ответ

0 голосов
/ 08 февраля 2020

Одна вещь, которую я заметил вне летучей мыши, это то, что 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);
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...