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

React TSX表单数据捕获异常:输入内容无法正常显示与提交

React TSX注册表单问题排查与后端提交方案

问题现象

开发注册表单时,输入内容时控制台仅显示当前单个字符,前端输入框无法正常显示输入内容。项目使用.tsx文件,相关代码及控制台输出如下:

表单代码

import { Link } from "react-router-dom";
import { useState } from "react";

const Signup: React.FC = () => {
  const [formData, setFormData] = useState({
    username: "",
    email: "",
    password: "",
  });

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = event.target;
    setFormData((prevFormData) => ({
      ...prevFormData,
      [name]: value,
    }));
    console.log(formData);
  };

  const handleSubmit = (event: React.FormEvent) => {
    event.preventDefault();

    const postData = new FormData();
    postData.append("username", formData.username);
    postData.append("email", formData.email);
    postData.append("password", formData.password);
    console.log(postData);
  };

  return (
    <>
      <div className="login-body">
        <div className="wrapper">
          <div className="form-wrapper sign-in">
            <form onSubmit={handleSubmit}>
              <h2 className="login-h2">Signup</h2>
              <div className="input-auth">
                <input
                  id="username"
                  type="text"
                  required
                  value={formData.username}
                  onChange={handleInputChange}
                  autoComplete="off"
                />
                <label htmlFor="username">Username</label>
              </div>
              <div className="input-auth">
                <input
                  id="email"
                  type="email"
                  required
                  autoComplete="off"
                  value={formData.email}
                  onChange={handleInputChange}
                />
                <label htmlFor="email">Email</label>
              </div>
              <div className="input-auth">
                <input
                  id="password"
                  type="password"
                  required
                  value={formData.password}
                  onChange={handleInputChange}
                  autoComplete="off"
                />
                <label htmlFor="password">Password</label>
              </div>
              <div className="remember">
                <label className="ml-2">
                  <input type="checkbox" /> I agree to the terms & conditions
                </label>
              </div>
              <button type="submit" className="login-button">
                Sign Up
              </button>
              <div className="signUp-link">
                <p>
                  Already have an account?
                  <Link to="/login" className="signUpBtn-link">
                    Login
                  </Link>
                </p>
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
};

export default Signup;

控制台输出

{username: '', email: '', password: '', "": 's'}
""
: 
"s"
email
: 
""
password
: 
""
username
: 
""

错误原因

  1. input缺失name属性:handleInputChange中通过event.target.name获取字段名,但所有input标签都未设置name属性,导致name为空字符串。更新状态时会给formData添加一个空键的属性,而非更新username/email/password,因此输入框绑定的value始终是初始空值,无法正常显示输入内容。
  2. 异步状态更新的日志问题:setFormData是异步操作,直接在其后调用console.log(formData)打印的是更新前的旧状态,这也是控制台显示异常数据的原因之一。

修复方案

1. 给input添加name属性

每个input标签添加与state字段对应的name属性,确保状态更新时能正确匹配字段:

// username输入框修改示例
<input
  id="username"
  name="username" // 新增name属性
  type="text"
  required
  value={formData.username}
  onChange={handleInputChange}
  autoComplete="off"
/>

同理,给email和password输入框分别添加name="email"和name="password"。

2. 正确打印更新后的状态

如果需要查看更新后的状态,可通过两种方式:

  • 在setFormData的回调中打印:
setFormData((prevFormData) => {
  const newFormData = {
    ...prevFormData,
    [name]: value,
  };
  console.log(newFormData);
  return newFormData;
});
  • 使用useEffect监听formData变化:
import { useEffect } from "react";

// 在组件内添加
useEffect(() => {
  console.log(formData);
}, [formData]);

表单数据提交到Node.js后端

前端提交(使用fetch)

修改handleSubmit方法,直接发送JSON格式数据到后端接口:

const handleSubmit = async (event: React.FormEvent) => {
  event.preventDefault();
  try {
    const response = await fetch("http://localhost:3000/api/signup", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(formData),
    });
    const result = await response.json();
    if (response.ok) {
      console.log("注册成功", result);
      // 可添加跳转或提示逻辑
    } else {
      console.error("注册失败", result);
    }
  } catch (error) {
    console.error("请求出错", error);
  }
};

Node.js后端接收(Express示例)

  1. 安装必要依赖:npm install express cors
  2. 编写后端接口:
const express = require("express");
const cors = require("cors");
const app = express();

// 配置中间件
app.use(cors());
app.use(express.json()); // 解析JSON格式的请求体

// 注册接口
app.post("/api/signup", (req, res) => {
  const { username, email, password } = req.body;
  // 可添加数据库存储逻辑
  console.log("收到注册数据:", { username, email, password });
  res.status(200).json({ message: "注册成功" });
});

app.listen(3000, () => {
  console.log("服务器运行在http://localhost:3000");
});

内容的提问来源于stack exchange,提问作者Muhammad Hassan Saeed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:15:03