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

Next.js表单无法输入内容问题求助

表单输入无法更新state的问题排查与修复

核心原因:表单控件缺失name属性

你的handleChange函数依赖e.target.name来匹配state里的字段,但所有<Input>和<Textarea>组件都没设置name属性,导致:

  • 直接用value绑定state时,输入内容无法触发state更新,控件始终停留在初始空值
  • 改用defaultValues时,控件进入非受控模式,能输入但state完全不同步,所以form对象始终为空

修复方案

给每个表单控件添加与state字段对应的name属性:

  • 姓名输入框加name="name"
  • 邮箱输入框加name="email"
  • 消息文本框加name="message"

修改后的完整代码

"use client";

import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Textarea } from "./ui/textarea";
import { User, MailIcon, ArrowRightIcon, MessageSquare } from "lucide-react";
import emailjs from "@emailjs/browser";
import { ChangeEvent, FormEvent, useRef, useState } from "react";

const Form = () => {
  const formRef = useRef<HTMLFormElement>(null);
  const [form, setForm] = useState({
    name: "",
    email: "",
    message: "",
  });

  const handleChange = (
    e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const { name, value } = e.target;

    setForm({ ...form, [name]: value });
  };

  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    console.log("Dati del form:", form);

    emailjs
      .send(
        "service_+++++",
        "template_++++++",
        {
          from_name: form.name,
          to_name: "Jhon Doe",
          from_email: form.email,
          to_email: "jhondoe1@gmail.com",
          message: form.message,
        },
        "WYI3ob++++++++"
      )
      .then(
        () => {
          alert("Thank you for your message!");

          setForm({
            name: "",
            email: "",
            message: "",
          });
        },
        (error: Error) => {
          console.log(error);
          alert("Something went wrong");
        }
      );
  };

  return (
    <form
      ref={formRef}
      onSubmit={handleSubmit}
      className="flex flex-col gap-y-4"
    >
      <div className="relative flex items-center">
        <Input
          onChange={handleChange}
          type="text"
          id="name"
          name="name"
          placeholder="Name"
          required
          value={form.name}
        />
        <User className="absolute right-6" size={20} />
      </div>
      <div className="relative flex items-center">
        <Input
          onChange={handleChange}
          type="email"
          id="email"
          name="email"
          placeholder="Email"
          required
          value={form.email}
        />
        <MailIcon className="absolute right-6" size={20} />
      </div>
      <div className="relative flex items-center">
        <Textarea
          onChange={handleChange}
          required
          name="message"
          placeholder="Type your message"
          value={form.message}
        />
        <MessageSquare className="absolute top-4 right-6" size={20} />
      </div>

      <Button className="flex items-center gap-x-1 max-w-[166px] rounded-[80px]">
        Let&apos; s Talk
        <ArrowRightIcon size={20} />
      </Button>
    </form>
  );
};

export default Form;

补充说明

id属性主要用于关联label或表单校验,name才是表单控件与state绑定的关键标识,两者功能不同不能混用,必须保证name值和state字段名完全一致,这样动态属性[name]才能正确匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:05:14