reactjs - 在 React 中使用 Hooks 停止/防止滚动到顶部重新渲染(需要实现无限滚动)

标签 reactjs react-hooks infinite-scroll

我正在尝试使用 React Hooks 设置无限滚动,我从节点后端正确获取数据(每个请求 3 个数据集),当我滚动时,新数据也被正确添加到数组(处于 loadedPlaces 状态),但页面在重新呈现时返回顶部,我需要防止这种行为。我该如何防止这种情况,下面是我的代码

import React, { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [page, setPage] = useState(1);
  const [loadedPlaces, setLoadedPlaces] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const getPlaces = async () => {
      try {
        setIsLoading(true);
        const url = `http://localhost:5000/api/places/user/${id}?page=${page}&size=3`;
        const responseData = await fetch(url);
        const data = await responseData.json();
        console.log(data);
        setLoadedPlaces((prev) => [...prev, ...data.places]);
        setIsLoading(false);
      } catch (error) {}
    };
    getPlaces();
  }, [page]);

  window.onscroll = function (e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      setPage(page + 1);
    }
  };

  return (
    <div className='App'>
      <h1>Infinite Scroll</h1>
      {!isLoading &&
        loadedPlaces.length > 0 &&
        loadedPlaces.map((place, index) => (
          <div key={index} className={"container"}>
            <h1>{place.location.lat}</h1>
            <h1>{place.location.lng}</h1>
            <h1>{place.title}</h1>
            <h1>{place.description}</h1>
            <h1>{place.address}</h1>
            <hr></hr>
          </div>
        ))}
    </div>
  );
}

export default App;

非常感谢任何帮助

最佳答案

发生这种情况是因为无论何时滚动你都在调用

window.onscroll = function (e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      setPage(page + 1);
    }
  };

它改变了页数,改变的页数导致再次运行

 useEffect(() => {
    const getPlaces = async () => {
      try {
        setIsLoading(true);
        const url = `http://localhost:5000/api/places/user/${id}?page=${page}&size=3`;
        const responseData = await fetch(url);
        const data = await responseData.json();
        console.log(data);
        setLoadedPlaces((prev) => [...prev, ...data.places]);
        setIsLoading(false);
      } catch (error) {}
    };
    getPlaces();
  }, [page]);

并且在该函数中,您正在执行 setIsLoading(true) 以便它再次呈现它,因为


{!isLoading && <-----
        loadedPlaces.length > 0 &&
        loadedPlaces.map((place, index) => (
          <div key={index} className={"container"}>
            <h1>{place.location.lat}</h1>
            <h1>{place.location.lng}</h1>
            <h1>{place.title}</h1>
            <h1>{place.description}</h1>
            <h1>{place.address}</h1>
            <hr></hr>
          </div>
        ))}

这会将您带到页面顶部

你可以试试这个方法:

import React, { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [page, setPage] = useState(1);
  const [loadedPlaces, setLoadedPlaces] = useState([]);
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const getPlaces = async () => {
      try {
        setIsLoading(true);
        const url = `http://localhost:5000/api/places/user/${id}?page=${page}&size=3`;
        const responseData = await fetch(url);
        const data = await responseData.json();
        console.log(data);
        setLoadedPlaces((prev) => [...prev, ...data.places]);
        setIsLoading(false);
      } catch (error) {}
    };
    getPlaces();
  }, [page]);

  window.onscroll = function (e) {
    if (
      window.innerHeight + document.documentElement.scrollTop ===
      document.documentElement.offsetHeight
    ) {
      setPage(page + 1);
    }
  };

  return (
    <div className='App'>
      <h1>Infinite Scroll</h1>
       {
        loadedPlaces.length > 0 &&
        loadedPlaces.map((place, index) => (
          <div key={index} className={"container"}>
            <h1>{place.location.lat}</h1>
            <h1>{place.location.lng}</h1>
            <h1>{place.title}</h1>
            <h1>{place.description}</h1>
            <h1>{place.address}</h1>
            <hr></hr>
          </div>
        ))}
    </div>
  );
}

export default App;

关于reactjs - 在 React 中使用 Hooks 停止/防止滚动到顶部重新渲染(需要实现无限滚动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68457639/

相关文章:

javascript - Laravel 5 分页 + 无限滚动 jQuery

javascript - 通过 express 从 mongo 获取数据,构建对象,并发送给 React

reactjs - Chromatic CLI 没有构建故事书

javascript - React-admin 在共享相同资源的两个列表上分隔过滤器

javascript - 确定在 react 中选中的复选框的方法(useState)

php - Prestashop blocklayered + 无限滚动问题

javascript - 拆分列(每个 50%)以相反方向滚动 - 连续/循环

reactjs - window.location.href 与 react-router-dom 的重定向实用程序

javascript - 更改子组件中的数据而不更改父组件中的数据

javascript - React hooks - 由于关闭而异步 setState 更新旧状态