reactjs - Next JS SSG如何实现无限滚动?

标签 reactjs typescript next.js

我按照 Next Js 文档和 Using Typescript 创建了一个 Markdown 博客。获取我使用的博客文章列表 getStaticProps作为docs建议。我尝试了一些 npm 包,它不起作用,或者我不知道如何完美设置。
如果有好的插件 定制 Hook , 请告诉我如何在 Next Js 静态站点生成中添加无限滚动功能。
此 GitHub 存储库中提供了项目源代码:https://github.com/vercel/next-learn-starter/blob/master/typescript-final/pages/index.tsx

最佳答案

我做了一些研究并创建了自己的 react 钩子(Hook)来在 Next JS 中实现无限滚动。所以,我正在回答我的问题。
如果有人有更好的方法,请不要忘记在这里分享。
我找到了两种工作方法。第一个使用 innerHeight 完成, scrollTop , offsetHeight值(value)观。它工作得很好,但不知何故我觉得这不是正确的方法。如果我错了,请纠正我。
第二种方法是通过Intersection Observer API异步观察目标元素交集的变化。 .首先,我创建了一个分页自定义 react Hook 来限制我的博客文章,然后我使用 IntersectionObserver 来获取下一页的博客文章。
使用分页.tsx:

import { useState } from "react";

function usePagination(data, itemsPerPage: number) {
  const [currentPage, setCurrentPage] = useState(1);

  const maxPage = Math.ceil(data.length / itemsPerPage);

  function currentData() {
    const begin = (currentPage - 1) * itemsPerPage;
    const end = begin + itemsPerPage;
    return data.slice(null, end);
  }

  function next() {
    setCurrentPage((currentPage) => Math.min(currentPage + 1, maxPage));
  }

  return { next, currentData, currentPage, maxPage };
}

export default usePagination;
索引.tsx:
import { GetStaticProps } from "next";
import { getSortedPostsData } from "../lib/posts";
import Layout from "../components/layout";
import usePagination from "../lib/Hooks/usePagination";
import { useRef, useState, useEffect } from "react";

export default function Home({
  allPostsData,
}: {
  allPostsData: {
    id: string;
    title: string;
    date: string;
    cover: string;
  }[];
}) {
  const { next, currentPage, currentData, maxPage } = usePagination(
    allPostsData,
    8
  );
  const currentPosts = currentData();
  const [element, setElement] = useState(null);

  const observer = useRef<IntersectionObserver>();
  const prevY = useRef(0);
  useEffect(() => {
    observer.current = new IntersectionObserver(
      (entries) => {
        const firstEntry = entries[0];
        const y = firstEntry.boundingClientRect.y;

        if (prevY.current > y) {
          next();
        }
        prevY.current = y;
      },
      { threshold: 0.5 }
    );
  }, []);

  useEffect(() => {
    const currentElement = element;
    const currentObserver = observer.current;

    if (currentElement) {
      currentObserver.observe(currentElement);
    }

    return () => {
      if (currentElement) {
        currentObserver.unobserve(currentElement);
      }
    };
  }, [element]);
  return (
    <Layout>

      <article className="w-full mt-12 flex flex-wrap items-center justify-center">
        {currentPosts &&
          currentPosts.map(({ id, title, date, cover }) => (
            <div key={id} // ......
            </div>
          ))}
      </article>
      {currentPage !== maxPage ? (
        <h1 ref={setElement}>Loading Posts...</h1>
      ) : (
        <h1>No more posts available...</h1>
      )}
    </Layout>
  );
}

export const getStaticProps: GetStaticProps = async () => {
  const allPostsData = getSortedPostsData();

  return {
    props: {
      allPostsData,
    },
  };
};

关于reactjs - Next JS SSG如何实现无限滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62994660/

相关文章:

javascript - 下一步.js。 docker 镜像所需的文件

javascript - 在 React 中,如何在多个选择下拉菜单之间更新状态,每个下拉菜单都有相同的选项?

javascript - 如何将 slider 范围输入的值居中? react 、NextJS、Tailwind

node.js - React Sortable Tree - 我可以通过查找树数据的类型来给出外部按钮 "Add node"吗?

angular - 为什么我得到 value undefined

javascript - AngularJS ngRepeat 清除批量数据时显示缓慢

typescript - Nest.js 无法解决对 TestingModule 的循环依赖

node.js - Kubernetes 上的 Node.js 容器中的 Axios 返回 "ECONNREFUSED 127.0.0.1:30561"?

javascript - 无法在 JSX 中渲染 bool 值?

reactjs - Material UI - 自动完成样式