如何在应用程序目录中制作依赖 useEffect 作为 props 的 Next.js 13 服务器端组件?

0 reactjs server-side-rendering next.js react-props react-hooks

我正在尝试在应用程序目录中编写一个 Next.js 13 时事通讯页面,该页面使用依赖于 useEffect 作为 props 的服务器端组件。useEffect 从 REST API 获取数据以获取将呈现页面内容的新闻通讯。我正在使用的代码如下。当我需要“使用客户端”进行交互时,我无法弄清楚如何配置服务器端组件以使其工作。如何确保服务器端组件在发送到客户端之前已渲染?

代码:

import Navbar from '@/components/navbar'
import Footer from '@/components/footer'
import Pagination from './pagination'
import IssueCards from './issueCards';
import { useState, useEffect } from 'react';
import axios from 'axios';


const Newsletters = () => {
    const [issues, setIssues] = useState([]);
    const [currentPage, setCurrentPage] = useState(1);
    const [issuesPerPage, setIssuesPerPage] = useState(5);

    useEffect(() => {
        const fetchIssue = async () => {
            const res = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API}/newsletters`)
            setIssues(res.data)
        }
        fetchIssue()
    }, [])
    
    // Change page
    const paginate = (pageNumber) => setCurrentPage(pageNumber);

    const indexOfLastIssue = currentPage * issuesPerPage;
    const indexOfFirstIssue = indexOfLastIssue - issuesPerPage;
    const currentIssues = issues.slice(indexOfFirstIssue, indexOfLastIssue)

    return (
        <>
            <Navbar />
            <div className="newsletter-container" id='newsletter-container'>
                <h1>Newsletters</h1>
                <hr></hr>
                <div className="newsletter-wrapper">
                    <IssueCards issues={currentIssues} />
                    <Pagination 
                        issuesPerPage={issuesPerPage} 
                        totalIssues={issues.length} 
                        paginate={paginate} 
                    />
                </div>
            </div>
            <Footer />
        </>
    );
}

export default Newsletters;
Run Code Online (Sandbox Code Playgroud)

如何配置依赖 useEffect 作为 props 的 Next.js 13 服务器端组件,并确保内容在发送到客户端之前呈现?

我尝试遵循服务器和客户端组件上的Nextjs 文档,但我不确定如何将 props 信息传递到服务器上。

Chr*_*mov 5

不幸的是,服务器组件不允许使用诸如 之类的钩子useEffect,请参阅此处的文档

您有两个主要选择:

  1. 获取数据的新方法
    服务器组件允许采用一种在组件中获取数据的新方法,如此处所述。
    这种方法看起来像这样:

    async function getData() {
      const res = await fetch('https://api.example.com/...');
      // The return value is *not* serialized
      // You can return Date, Map, Set, etc.
    
      // Recommendation: handle errors
      if (!res.ok) {
        // This will activate the closest `error.js` Error Boundary
        throw new Error('Failed to fetch data');
      }
    
      return res.json();
    }
    
    export default async function Page() {
     const data = await getData();
    
     return <main></main>;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 恢复到客户端组件
    您的另一个选择是使用use client文件顶部的指令并将 Newsletter 保留为客户端组件。当然,这样您就不会获得服务器组件的好处,但这将阻止您大幅更改代码。另外,请记住服务器组件仍处于测试阶段。