You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13.5 App Router:服务端页面传props到客户端组件未定义

问题:Next.js 13.5 App Router中服务端页面向客户端组件传递Props值为undefined

我正在使用Next.js v13.5的App Router,拥有一个/dashboard服务端页面,页面内包含ApiKeyOptions客户端组件。当我从dashboard页面向ApiKeyOptions组件传递props时,获取到的值为undefined。其他功能都正常运行,没有报错,只是key props的值为undefined。

/dashboard 服务端页面代码

import ApiKeyOptions from "@/components/client-compoents/ApiKeyOptions";
import KeyStatics from "@/components/client-compoents/KeyStatics";
import RequestApiKey from "@/components/client-compoents/RequestApiKey";
import authoptions from "@/lib/authOptions";
import { db } from "@/lib/db/db";
import { getServerSession } from "next-auth";
import React from "react";

const page = async () => {
  const session = await getServerSession(authoptions);
  const apiKey = await db.apiKey.findFirst({
    where: {
      userId: session?.user.id,
      enabled: true,
    },
  });

  return (
    <section className="container mt-24 sm:px-16 ">
      <div className="flex w-full justify-between items-center">
        <h2>
          Howdy, <span className="font-medium">{session?.user.name} ?</span>
        </h2>
        <img
          src={session?.user.image!}
          alt={session?.user.name as string}
          width={45}
          height={45}
          referrerPolicy="no-referrer"
          className="border-2 border-solid border-slate-500 p-[2px] rounded-full"
        />
      </div>
      {apiKey && (
        <div className="flex items-center gap-x-4 mt-2">
          <h2 className="font-light text-sm p-2 bg-[rgba(0,0,0,0.15)] w-fit rounded-md">
            {apiKey?.key}
          </h2>
          <ApiKeyOptions key={"whatever"} />
        </div>
      )}
      <div className="flex justify-center mt-6">
        {apiKey ? <KeyStatics /> : <RequestApiKey />}
      </div>
    </section>
  );
};

export default page;

ApiKeyOptions 客户端组件代码

"use client";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { DotsVerticalIcon } from "@radix-ui/react-icons";
import { useToast } from "../ui/use-toast";

export default function ApiKeyOptions({ key }: { key: string }) {
  console.log(key);
  const { toast } = useToast();

  function copyText(text: string) {
    navigator.clipboard.writeText(text);
    toast({
      description: "Copied to clipboard.",
    });
  }
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline" size="icon">
          <DotsVerticalIcon className="h-4 w-4" />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent className="w-40 dark:bg-slate-700 text-left">
        <Button
          variant="ghost"
          className="block w-full hover:dark:bg-slate-800 text-left"
          // onClick={() => copyText(key)}
        >
          Copy
        </Button>
        <DropdownMenuSeparator />
        <Button
          variant="ghost"
          className="block w-full hover:dark:bg-slate-800 text-left"
        >
          Revoke
        </Button>
        <DropdownMenuSeparator />
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

解决方案

问题根源

key是React的特殊保留属性,专门用于在列表渲染场景中标识组件实例,帮助React高效更新DOM。这个属性会被React内部处理,不会作为普通props传递给组件,所以你在ApiKeyOptions中尝试获取key时得到的是undefined。

修复步骤

  1. 修改服务端页面的props传递名称
    将传递的props名称从key改为自定义名称(比如apiKey),同时传递真实的API密钥值:

    // 在/dashboard页面中修改组件调用
    <ApiKeyOptions apiKey={apiKey.key} />
    

    如果你需要给组件设置React的key属性(比如后续有列表渲染场景),可以同时添加:

    <ApiKeyOptions key={apiKey.id} apiKey={apiKey.key} />
    
  2. 修改客户端组件的props接收逻辑
    同步修改组件的props接收参数,并更新相关逻辑:

    // ApiKeyOptions组件中修改
    export default function ApiKeyOptions({ apiKey }: { apiKey: string }) {
      console.log(apiKey); // 现在会输出正确的API密钥
      const { toast } = useToast();
    
      function copyText(text: string) {
        navigator.clipboard.writeText(text);
        toast({
          description: "Copied to clipboard.",
        });
      }
      return (
        <DropdownMenu>
          {/* ... 其他代码 */}
          <Button
            variant="ghost"
            className="block w-full hover:dark:bg-slate-800 text-left"
            onClick={() => copyText(apiKey)} // 这里改为apiKey
          >
            Copy
          </Button>
          {/* ... 其他代码 */}
        </DropdownMenu>
      );
    }
    

验证

完成修改后,重新运行项目,ApiKeyOptions组件就能正确接收到传递的API密钥值,复制功能也可以正常使用。


内容的提问来源于stack exchange,提问作者Pawan Poudel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:12:16