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

Next.js表单同时使用服务端与客户端事件处理器的问题

问题解决思路与代码实现

核心问题原因

Next.js App Router 默认的页面组件是服务端组件(Server Component),这类组件仅在服务端完成渲染,不会在客户端加载和执行 JavaScript,因此无法支持 onClick 这类客户端交互事件。而你需要同时保留服务端的表单提交逻辑(createGame 带 'use server')和客户端的交互功能,所以需要拆分组件,将交互部分抽离为客户端组件。

解决方案:拆分服务端与客户端逻辑

把需要交互的表单部分单独拆成一个带 'use client' 指令的客户端组件,服务端的 createGame 函数可以作为 props 传递给客户端组件使用,既保留数据库写入的服务端能力,又实现客户端交互。

1. 改造父页面(仍为服务端组件)

保留服务端的 createGame 函数,渲染抽离出的客户端表单组件:

// src/app/game/new/page.tsx
import GameForm from './GameForm';

export default function Page() {
  async function createGame(formData: FormData) {
    'use server';
    // ... 向数据库创建游戏条目的代码
  }

  return <GameForm createGame={createGame} />;
}

2. 新建客户端表单组件

创建带 'use client' 的组件,处理 handleGeneratePrompt 交互逻辑,并接收父组件传递的服务端表单提交函数:

// src/app/game/new/GameForm.tsx
'use client';

import { useState } from 'react';
// 导入你的prompt生成逻辑
import { generatePrompt } from './game/prompt/actions';

type Props = {
  createGame: (formData: FormData) => Promise<void>;
};

export default function GameForm({ createGame }: Props) {
  const [prompt, setPrompt] = useState('');

  async function handleGeneratePrompt() {
    console.log('Executed handleGeneratePrompt');
    // 调用prompt生成接口/逻辑
    const generatedPrompt = await generatePrompt();
    // 更新输入框内容
    setPrompt(generatedPrompt);
  }

  return (
    <div>
      <form action={createGame}>
        <input
          type="text"
          name="prompt"
          value={prompt}
          onChange={(e) => setPrompt(e.target.value)}
        />
        {/* 必须加type="button",避免触发表单默认提交 */}
        <button type="button" onClick={handleGeneratePrompt}>
          Generate a prompt
        </button>
        <button type="submit">Create new game</button>
      </form>
    </div>
  );
}

关键细节说明

  • 'use client' 标记的组件会在客户端加载并执行,支持所有 React 交互特性(如 onClick、useState)。
  • 服务端的 createGame 函数可以直接作为 props 传递给客户端组件,Next.js 支持将 Server Action 从服务端组件传递到客户端组件,表单的 action 属性可直接使用该函数。
  • 给「Generate a prompt」按钮添加 type="button",避免点击时触发表单默认提交行为,确保只执行交互逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 04:35:00