如何在Next.js 13的初始渲染期间使用服务器函数?

How to use server functions during initial render in Next.js 13?

提问人:Eugène-René 提问时间:9/24/2023 更新时间:9/24/2023 访问量:34

问:

我正在尝试创建一个虚拟博客项目以更好地理解 Next 13,当我试图将分页器装箱时,我遇到了一个块。目前,我有一个在服务器上运行的帖子目录,并使用一个名为“PostPageComponent”的组件。

"use server";
import PostsPageComponent from "@/app/components/posts/Posts";

function PostsPage() {
  return (
    <>
      <PostsPageComponent />
    </>
  );
}

export default PostsPage;

然后我有前面提到的组件,它在客户端上运行,它有两个功能,“Posts”和“PostComponentsPage”,其中第一个从帖子的本地目录中获取信息并将它们列为单个帖子,而第二个还添加了一个分页器组件。

"use client";
import { useState } from "react";

import getPosts from "@/app/lib/getPosts/getPosts";
import Link from "next/link";
import Paginator from "./Paginator";

export function Posts({ page = 1, read }) {
  const posts = getPosts(page, read);

  return (
    <>
      <ul>
        {Array.isArray(posts) &&
          posts.map((post) => {
            return (
              <li key={post.fileName}>
                <div>
                  <Link href={`/posts/${post.fileName}`}>
                    {post.fileName.replace(/\.mdx$/, "")}
                  </Link>
                  <p>{post.fileContents.slice(0, 50)}...</p>
                </div>
              </li>
            );
          })}
      </ul>
    </>
  );
}

export default function PostsPageComponent() {
  const [currentPage, setCurrentPage] = useState(1);
  const postsPerPage = 10;
  return (
    <>
      <div>
        <Posts page={currentPage} read={postsPerPage} />

        <Paginator currentPage={currentPage} setCurrentPage={setCurrentPage} />
      </div>
    </>
  );
}

这是分页器。

export default function Paginator({ currentPage, setCurrentPage }) {
  return (
    <>
      <div>
        {currentPage > 1 && (
          <button onClick={() => setCurrentPage(currentPage - 1)}>
            Previous
          </button>
        )}

        <button onClick={() => setCurrentPage(currentPage + 1)}>Next</button>
      </div>
    </>
  );
}

最后是“getPosts”函数。

"use server";
import fs from "fs";
import path from "path";

export const getPostsDirectory = async () => {
  return path.join(process.cwd(), "posts");
};

export default async function getPosts(page = 1, n) {
  const startIndex = (page - 1) * n;
  const endIndex = page * n;
  const postsDirectory = await getPostsDirectory();
  const fileNames = fs.readdirSync(postsDirectory).splice(startIndex, endIndex);

  const posts = fileNames
    .map((fileName) => {
      const fullPath = path.join(postsDirectory, `${fileName}`);
      if (fs.statSync(fullPath).isFile()) {
        const fileContents = fs.readFileSync(fullPath, "utf8");
        const parsedFileName = fileName.replace(/\.[^/.]+$/, ""); // Remove anything after (including) the dot
        return {
          fileName: parsedFileName,
          fileContents: fileContents,
        };
      }
    })
    .filter(Boolean);

  return posts;
}

我还必须补充一点,在我开始添加分页器之前,博客的核心功能运行良好,我为代码的意大利面条感到抱歉。我对新的 Next.js 还没有太多经验。

一如既往,谢谢!

JavaScript ReactJS Next.js 服务器端渲染 客户端

评论


答: 暂无答案