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

ReactJS点击Transfer按钮报preventDefault未定义TypeError问题

问题现象
  • React项目中点击Transfer按钮触发TypeError报错,对应业务文件为transferproduct.js
  • 控制台错误信息:transferproduct.js:35 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'preventDefault')
  • 报错截图:TypeError控制台报错截图
问题根因

代码存在多处逻辑错误,共同导致报错:

  1. 事件绑定方式错误:仅给提交按钮绑定onClick事件,未给<form>标签绑定onSubmit处理逻辑。按钮type="submit"属性会触发浏览器原生表单提交,导致页面刷新,React合成事件对象被回收,后续访问e.preventDefault()时事件对象已为undefined
  2. 事件阻止逻辑位置错误:handleSubmit函数中先构造提交参数,后调用e.preventDefault(),没有在事件触发第一时间阻止默认提交行为,给页面刷新留了窗口期
  3. axios响应字段拼写错误:axios封装的响应对象中,接口返回的业务数据存放在data字段,代码中错误解构为datas,实际拿到的值为undefined,后续执行JSON.parse(datas)会触发二次报错
  4. 状态读取时机错误:React的setState是异步执行的,调用setProduct(parseData)后立即读取product.cost时,拿到的还是初始值空数组,不存在cost属性,会触发后续类型错误
  5. 冗余逻辑和边界缺失:handleChange中无意义调用e.preventDefault(),localStorage读取产品配置时未做空值兜底,都会埋下额外报错隐患
修复方案

按以下步骤修改代码即可解决问题:

  • 将提交事件绑定到<form>标签的onSubmit属性上,移除按钮上的onClick绑定
  • 把e.preventDefault()放到handleSubmit函数的第一行,事件触发后立即阻止默认表单提交
  • 修正axios响应解构的字段名,将错误的datas改为data
  • 删除handleChange中多余的e.preventDefault()调用
  • 预算判断逻辑直接使用接口返回的parseData做判断,不要依赖还未更新的product状态
  • 给localStorage读取的配置增加空值兜底,避免取值为null时读取属性报错

修复后的完整代码如下:

import React from 'react';
import { useState } from 'react';
import axios from 'axios';

// 增加空值兜底
const props = JSON.parse(localStorage.getItem('products')) || { budget: 0 };

const TransferProduct = () => {
  const [product, setProduct] = useState([]);

  const [data, setData] = useState({
    id: '',
    oname: '',
    area: '',
  });

  const handleChange = (e) => {
    // 删除多余的preventDefault调用
    const value = e.target.value;
    setData({
      ...data,
      [e.target.name]: value,
    });
  };

  const handleSubmit = async (e) => {
    // 第一时间阻止默认提交
    e.preventDefault();
    const userData = {
      id: data.id,
      newOwner: data.oname,
      newArea: data.area,
    };

    try {
      // 修正axios响应字段名
      const { data: resData } = await axios.get(
        'http://localhost:8080/api/QueryProductById/' + data.id
      );

      const parseData = JSON.parse(resData);
      // 直接使用接口返回值做判断,不依赖未更新的state
      if (parseData.cost < props.budget) {
        console.log('预算不足,无法完成产品转移');
        return;
      }

      // 预算校验通过后再发起转移请求
      const response = await axios.put(
        'http://localhost:8080/api/TransferProduct/' + data.id, 
        userData
      );
      console.log('产品转移成功', response);
      setProduct(parseData);
    } catch (error) {
      if (error.response) {
        console.log('服务端返回错误:', error.response);
      } else if (error.request) {
        console.log('网络异常,请求未发送成功');
      } else {
        console.log('请求配置错误:', error);
      }
    }
  };

  return (
    <div>
      {/* 给form绑定提交事件 */}
      <form onSubmit={handleSubmit}>
        <label htmlFor='header-search'>
          <span className='visually-hidden'>From</span>
        </label>
        <input
          type='text'
          name='id'
          value={data.id}
          placeholder='ID'
          onChange={handleChange}
        />
        <label htmlFor='header-search'>
          <span className='visually-hidden'>TO</span>
        </label>
        <input
          type='text'
          name='oname'
          value={data.oname}
          placeholder='Enter New Owner'
          onChange={handleChange}
        />

        <label htmlFor='header-search'>
          <span className='visually-hidden'>TO</span>
        </label>
        <input
          type='text'
          name='area'
          value={data.area}
          placeholder='Enter new Location'
          onChange={handleChange}
        />

        <button type='submit'>
          Transfer
        </button>
      </form>
    </div>
  );
};

export default TransferProduct;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 23:33:21