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

React受控组件表单报错:TypeError: Cannot read properties of null (reading 'name')

React受控表单更新State时出现TypeError: Cannot read properties of null (reading 'name')的原因及解决方法

问题描述

在React中创建简单受控组件表单时,onChange事件里直接执行console.log(event.target.name)能正常输出,但使用JavaScript计算属性更新state时,抛出错误:TypeError: Cannot read properties of null (reading 'name')。此前用相同逻辑创建过多个可正常运行的项目,本次问题突发。

问题原因

  • React的合成事件(SyntheticEvent)采用事件池复用机制:事件处理函数同步执行完成后,React会清空事件对象的所有属性,并将其放回事件池供后续事件复用。
  • setContactFormValues的回调函数是异步执行的,当回调触发时,原事件对象已被React回收,event.target变为null,此时读取event.target.name自然报错。
  • 而开头的console.log(event.target.name)能正常运行,是因为这行代码属于同步执行,此时事件对象还未被回收。

解决方法

方法1:提前解构事件属性(推荐)

在调用setContactFormValues之前,将event.target的name和value提取到变量中,避免后续访问已被回收的事件对象:

const handleChange = (event) => {
  const { name, value } = event.target; // 提前解构保存属性
  setContactFormValues((prevValues) => ({
    ...prevValues,
    [name]: value
  }));
};

方法2:使用event.persist()保留事件对象

调用event.persist()可以阻止React回收当前事件对象,使其属性保持可用:

const handleChange = (event) => {
  event.persist(); // 禁用事件对象的池化复用
  setContactFormValues((prevValues) => ({
    ...prevValues,
    [event.target.name]: event.target.value
  }));
};

修正后的完整代码

import "./Contact.css";
import React from "react";

const Contact = () => {
  const [contactFormValues, setContactFormValues] = React.useState({
    fName: "",
    lName: "",
    email: "",
    phone: "",
    message: "",
  });
 
  const handleChange = (event) => {
    const { name, value } = event.target;
    setContactFormValues((prevValues) => ({
      ...prevValues,
      [name]: value
    }));
  };

  const handleSubmit = async (event) => {
    event.preventDefault();
    console.log(contactFormValues);
  }
  return (
    <>
      <div className="contact-form">
        <div className="contact-container">
          <div className="left-section">
            <div className="title">
              <h1>Write Us</h1>
            </div>
            <div className="row">
              <div className="contact-sub-row">
                <label className="contact-label">First Name</label>
                <input
                  className="contact-input"
                  type="text"
                  name="fName"
                  onChange={handleChange}
                  value={contactFormValues.fName}
                  required
                />
              </div>

              <div className="contact-sub-row">
                <label className="contact-label">Last Name</label>
                <input
                  className="contact-input"
                  type="text"
                  name="lName"
                  onChange={handleChange}
                  value={contactFormValues.lName}
                  required
                />
              </div>
            </div>

            <div className="contact-sub-row">
              <label className="contact-label">Email</label>
              <input
                className="contact-input is-success"
                type="email"
                name="email"
                onChange={handleChange}
                value={contactFormValues.email}
                required
              />
            </div>

            <div className="contact-sub-row">
              <label className="contact-label">Phone</label>
              <input
                className="contact-input"
                type="tel"
                placeholder="1-123-456-7890"
                maxlength="20"
                name="phone"
                onChange={handleChange}
                value={contactFormValues.phone}
                required
              />
            </div>
          </div>
          <div className="right-section">
            <div className="your-message">
              <label className="contact-label">Message</label>
              <textarea
                className="contact-textarea"
                name="message"
                placeholder="Write text here..."
                onChange={handleChange}
                value={contactFormValues.message}
                required
              ></textarea>
            </div>
            <div className="contact-btns">
              <button className="submit-btn" onClick={handleSubmit}>SEND MESSAGE</button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default Contact;

(注:恢复了代码中被注释的value属性,确保所有输入框均为标准受控组件)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 06:05:50