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

使用自定义输入Hook清空React表单时遇报错,求解决方法

React表单提交后无法清空的问题解决

问题根源

你自定义的useFormFields Hook返回的第二个参数是处理输入变化的事件回调函数,并非直接更新state的setValues方法。当你在handleSubmit里调用setFormData(data)时,data会被当成event传入回调函数,而普通对象没有target属性,所以会抛出Cannot destructure property 'target' of 'event' as it is undefined的错误。

另外,你当前的输入框没有绑定value属性,属于非受控组件,即使state被重置,输入框的显示内容也不会同步更新,这也是表单无法清空的隐性问题。


解决方案一:给Hook添加重置方法

修改useFormFields,新增一个专门的重置函数并返回:

export function useFormFields(initialState) {
  const [fields, setValues] = useState(initialState);

  // 新增重置表单的函数
  const resetFields = () => {
    setValues(initialState);
  };

  return [
    fields,
    function(event) {
      try {
        const { name, value, type, checked } = event.target;
        setValues({
          ...fields,
          [name]: type === "checkbox" ? checked : value,
        });
      } catch (err) {
        console.log(err);       
      }
    },
    resetFields // 返回重置函数
  ];
}

在组件中调用并使用重置函数,同时给输入框绑定value:

function NewMachine() {
  const initialData = {
    user_level:"",  
    name: "",
    email: "",
  };
  // 解构出重置函数
  const [formData, setFormData, resetForm] = useFormFields(initialData);
  
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
    resetForm(); // 调用重置函数清空表单
  };

  return (
    <div>
      <form onSubmit={handleSubmit} autoComplete="off">
        <input
          placeholder="Enter Name"
          className="form-control"
          id="name"
          name="name"
          onChange={setFormData}
          value={formData.name} // 绑定value,让输入框成为受控组件
          required
        />
        {/* 其他字段也要同步绑定对应的value */}
        <button className="float-right btn btn-secondary" type="submit">
          Create New User
        </button>
      </form>
    </div>
  );
}

解决方案二:兼容事件和对象输入的回调函数

如果不想新增重置函数,可以修改Hook里的回调,让它既能处理事件,也能直接接收对象更新state:

export function useFormFields(initialState) {
  const [fields, setValues] = useState(initialState);

  return [
    fields,
    function(input) {
      // 判断传入的是事件对象还是普通更新对象
      if (input.target) {
        try {
          const { name, value, type, checked } = input.target;
          setValues({
            ...fields,
            [name]: type === "checkbox" ? checked : value,
          });
        } catch (err) {
          console.log(err);       
        }
      } else {
        // 传入对象时直接更新state
        setValues(input);
      }
    },
  ];
}

组件中直接调用setFormData传入初始对象,同时绑定输入框的value:

function NewMachine() {
  const initialData = {
    user_level:"",  
    name: "",
    email: "",
  };
  const [formData, setFormData] = useFormFields(initialData);
  
  const handleSubmit = (e) => {
    e.preventDefault();
    console.log(formData);
    setFormData(initialData); // 直接传入初始对象重置表单
  };

  return (
    <div>
      <form onSubmit={handleSubmit} autoComplete="off">
        <input
          placeholder="Enter Name"
          className="form-control"
          id="name"
          name="name"
          onChange={setFormData}
          value={formData.name} // 绑定value同步显示
          required
        />
        {/* 其他字段同理绑定value */}
        <button className="float-right btn btn-secondary" type="submit">
          Create New User
        </button>
      </form>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:11:11