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

Next.js中ShadCN Combobox表单提交传递planeId数据问题

解决ShadCN Combobox嵌入表单时提交planeId到FormData的问题

ShadCN的Combobox组件基于Command实现,不属于原生表单控件,直接给Combobox.Item加name/id不会被FormData捕获。核心思路是用隐藏的原生input同步选中的planeId,让表单提交时自动带上这个字段。

基础方案(无需额外依赖)

通过React状态管理选中的planeId,绑定到隐藏input的value上:

"use client";

import { useState } from "react";
import { Combobox } from "@/components/ui/combobox";

// 示例飞机数据
const planes = [
  { id: "1", name: "波音737" },
  { id: "2", name: "空客A320" },
  { id: "3", name: "C919" },
];

export default function PlaneForm() {
  const [selectedPlaneId, setSelectedPlaneId] = useState("");

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    console.log("FormData内容:", Object.fromEntries(formData));
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 关键:隐藏input,name设为planeId,值同步选中项的ID */}
      <input
        type="hidden"
        name="planeId"
        value={selectedPlaneId}
        onChange={() => {}} // 避免React受控组件警告
      />

      <Combobox>
        <Combobox.Input placeholder="选择飞机" />
        <Combobox.Content>
          {planes.map((plane) => (
            <Combobox.Item
              key={plane.id}
              value={plane.id}
              onSelect={() => setSelectedPlaneId(plane.id)}
            >
              {plane.name}
            </Combobox.Item>
          ))}
        </Combobox.Content>
      </Combobox>

      {/* 其他表单字段示例 */}
      <div className="mt-4">
        <label className="block mb-1">航班号</label>
        <input type="text" name="flightNumber" className="border rounded px-2 py-1" />
      </div>

      <button type="submit" className="mt-4 bg-blue-500 text-white px-4 py-2 rounded">
        提交表单
      </button>
    </form>
  );
}

React Hook Form方案(适合复杂表单)

如果项目用React Hook Form,可以通过setValue同步选中值到注册的隐藏input:

"use client";

import { useForm } from "react-hook-form";
import { Combobox } from "@/components/ui/combobox";

const planes = [
  { id: "1", name: "波音737" },
  { id: "2", name: "空客A320" },
  { id: "3", name: "C919" },
];

type FormValues = {
  planeId: string;
  flightNumber: string;
};

export default function PlaneForm() {
  const { register, handleSubmit, setValue } = useForm<FormValues>();

  const onSubmit = (data: FormValues) => {
    console.log("表单数据:", data);
    // 转成FormData的方式
    const formData = new FormData();
    formData.append("planeId", data.planeId);
    formData.append("flightNumber", data.flightNumber);
    console.log("FormData内容:", Object.fromEntries(formData));
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {/* 注册隐藏input */}
      <input type="hidden" {...register("planeId")} />

      <Combobox>
        <Combobox.Input placeholder="选择飞机" />
        <Combobox.Content>
          {planes.map((plane) => (
            <Combobox.Item
              key={plane.id}
              value={plane.id}
              onSelect={() => setValue("planeId", plane.id)}
            >
              {plane.name}
            </Combobox.Item>
          ))}
        </Combobox.Content>
      </Combobox>

      <div className="mt-4">
        <label className="block mb-1">航班号</label>
        <input type="text" {...register("flightNumber")} className="border rounded px-2 py-1" />
      </div>

      <button type="submit" className="mt-4 bg-blue-500 text-white px-4 py-2 rounded">
        提交表单
      </button>
    </form>
  );
}

原理说明

  • 隐藏input是原生表单控件,表单提交时会自动将其name和value加入FormData。
  • 通过Combobox.Item的onSelect事件,将选中的飞机ID同步到隐藏input的value中,确保提交时数据一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:58:11