React 服务器组件错误:初始渲染期间无法调用服务器函数

Re-*_*lo 7 javascript reactjs next.js next.js13

我有一个名为 CampaignTable 的客户端组件。CampaignTable 组件需要一个列对象来呈现列。在我的列对象中,我导入了一个名为 CampaignActions 的服务器组件。这是一个简单的下拉菜单,我在其中执行 api 调用来获取一些数据并在弹出窗口中使用该数据。

但是,由于 API 调用是在 CampaignActions 组件中执行的,因此我的页面变得非常慢,并且收到一条错误消息:

错误:在初始渲染期间无法调用服务器函数。这将创建一个获取瀑布。尝试使用服务器组件将数据传递给客户端组件。

然而,据我了解,该组件已经是一个 React Server 组件。我可以通过删除异步并在顶级页面中执行 api 调用并将数据作为 props 向下传递来解决该问题,例如:

页面 > 营销活动表 > 营销活动操作。

但我想知道为什么我的方法是错误的/导致问题。因为如果我可以在需要它的组件中执行 api 调用,而不是将其传递下去,那就太好了。

这是我的代码

'use client'
import React from "react";

const CampaignTable = (props: CampaignTableProps) => {
const campaignColumns = useMemo(() => (
    [
        columnHelper.accessor("id", {
            header: () => "ID",
            cell: info => info.getValue()
        }),
        columnHelper.display({
            id: "socials",
            header: () => "Actions",
            cell: ({row}) => {
                return (
                    <CampaignActions {...row.original}/>
                )
            }
        }),
    ]
), [])

return (

    <DataTable  
        data={props.campaigns || []}
        columns={campaignColumns}
    />
)}
Run Code Online (Sandbox Code Playgroud)

我的 CampaignActions 代码

async function CampaignActions(props: Campaign){
const {data: clients} = await getAllClients().then((res) => res);
return (
    <DataTableActions
        edit={{
            onEdit: async () => {
                await openUpdateCampaignModal({
                    ...props,
                    clients: clients ?? [],
                })
            }
        }}
    />
)}
Run Code Online (Sandbox Code Playgroud)

Ada*_*kis 9

我想我在开始赏金后就明白了这一点。答案就隐藏在众目睽睽之下。

错误:在初始渲染期间无法调用服务器函数。

服务器功能,不要与服务器组件混淆。我将冒险假设你的

getAllClients()

函数位于顶部带有“use server”的文件中,使其成为服务器操作(或服务器函数,如错误消息中所称)。

这是在初始渲染期间无法调用的。服务器操作旨在作为用户交互的一部分进行调用。用户单击一个按钮,该按钮调用服务器操作。

服务器操作很特殊,会导致网络往返。这就是为什么 React 不允许你在初始渲染期间调用它们。

因此,让获取数据的功能不是服务器操作,这应该对您有用。


小智 -3

您面临的问题是由于 React Server Components (RSC) 的工作方式造成的。它们的设计目的不是在初始渲染期间获取数据,以避免出现“获取瀑布”场景,这会减慢应用程序的渲染速度。

在您的情况下,CampaignActions 尝试在初始渲染期间获取数据,因此出现错误。尽管它是一个服务器组件,但现阶段仍然不允许它获取数据。

解决这个问题的一个好方法是获取组件树中更高层的数据并将其作为 props 向下传递。这样,数据只需获取一次即可由多个组件使用,从而提高性能。或者,考虑使用 Redux 或 MobX 等状态管理库来管理应用程序的状态。

您的方法不一定是错误的,但由于 RSC 的限制,它会导致问题。在需要数据的组件中获取数据可能看起来很方便,但它可能会导致性能问题和更复杂的状态管理。因此,通常最好在更高级别获取数据并将其作为 props 向下传递。希望这可以帮助!

  • 这个答案显然是错误的。RSC 绝对“设计”为直接在渲染主体内部获取数据。有问题的错误消息是关于服务器*功能*而不是服务器*组件* (2认同)