Next.js 13.4中'use server'为何无法生效?
核心原因
渲染阶段无法修改Cookie
你在Server Component渲染过程中直接调用了testCookie函数,但Next.js明确规定:Server Component渲染时仅支持读取Cookie,修改Cookie的操作只能在用户触发的Server Action或者Route Handler中执行,渲染阶段属于只读上下文,不允许这类副作用操作。Server Action定义不符合规范
你把带有"use server"标记的testCookie写成了组件内部的嵌套函数,这种写法无法被Next.js正确识别为有效的Server Action。Server Action需要是顶层导出的函数,或是在组件中单独定义、通过用户交互(比如点击按钮、提交表单)触发调用的函数,不能嵌套在组件执行逻辑内直接同步调用。导入路径不规范
你使用了next/dist/client/components/headers这种内部私有路径导入cookies,正确的导入路径应该是next/headers——虽然这不是报错的直接原因,但可能引发其他潜在问题。
修正方案
方案1:用表单触发Server Action(推荐,符合Next.js规范)
将testCookie改为顶层函数,通过表单提交触发执行:
import { cookies } from "next/headers"; type SearchParams = { searchParams: { code: string; }; }; // 顶层定义Server Action async function testCookie() { "use server"; cookies().set("test", "test"); } export default async function EmailLoginPage({ searchParams }: SearchParams) { return ( <form action={testCookie}> <button type="submit">设置Cookie</button> </form> ); }
方案2:用Route Handler处理Cookie设置
如果需要页面加载时自动设置Cookie,可以创建一个接口处理:
// app/api/set-cookie/route.ts import { cookies } from "next/headers"; import { NextResponse } from "next/server"; export async function GET() { cookies().set("test", "test"); return NextResponse.json({ success: true }); }
然后在客户端组件中请求该接口:
// app/email-login/page.tsx "use client"; import { useEffect } from "react"; type SearchParams = { searchParams: { code: string; }; }; export default function EmailLoginPage({ searchParams }: SearchParams) { useEffect(() => { fetch("/api/set-cookie"); }, []); return <>></>; }
关键提醒
Server Action必须由用户交互触发,不能在Server Component渲染时直接调用——这是Next.js的设计规则,目的是避免渲染阶段产生意外副作用。另外一定要使用官方指定的next/headers导入cookies,不要使用内部私有路径。
内容的提问来源于stack exchange,提问作者gndy Br

