React表单onSubmit事件失效,默认提交至根路径问题求助
React表单提交Flask后端失败问题修复
核心问题
- 表单默认提交行为未被阻止,导致请求以GET/错误POST路径发送
- 绑定的
onSubmit函数未执行,alert无响应 - Flask后端数据接收逻辑与前端发送格式不匹配
React代码错误修复
1. 修正方法拼写错误:e.preventDefaults() → e.preventDefault()
这是onSubmit函数不执行的核心原因,方法名写错导致默认表单提交行为未被拦截,函数后续代码(包括alert)完全不会运行。
2. 修正数据转换方法:Object.formEntries → Object.fromEntries
formEntries是不存在的API,正确方法为fromEntries,用于将FormData对象转换为普通JSON对象。
3. 修正Fetch请求格式
- 发送JSON数据时必须设置
Content-Type: application/json请求头 - 需用
JSON.stringify()将对象转换为JSON字符串后再作为请求体 - 后端返回JSON格式数据,需用
response.json()解析,而非不存在的response.formData
修复后的React组件代码
import React, { useState } from 'react'; export default function PaymentForm() { const [startDate, setStartDate] = useState(); const [endDate, setEndDate] = useState(); const [frequency, setFrequency] = useState(); const [payDates, setPayDates] = useState(); const [isError, setError] = useState(false); // React组件需首字母大写 const ErrorMsg = ({ hasError }) => { if (hasError) return <p>Error occurred</p>; return null; }; async function submitData(data) { try { const response = await fetch('/get_dates', { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data) }); const res = await response.json(); setPayDates(res.frequency_dates); } catch (e) { setError(true); } } function handlePaymentForm(e) { e.preventDefault(); // 修正方法名拼写 alert("ran"); const form = e.target; const formData = new FormData(form); const jsonData = Object.fromEntries(formData); // 修正数据转换方法 submitData(jsonData); } return ( <React.Fragment> <p className="text-gray-500 font-bold mt-10">Schedule Payments</p> <form onSubmit={handlePaymentForm}> <label>Start Date: <input name="start_date" type="date" onChange={(e) => setStartDate(e.target.value)} /></label> <br /> <label>End Date: <input name="end_date" type="date" onChange={(e) => setEndDate(e.target.value)} /></label> <br /> <label> <select name="frequency" onChange={(e) => setFrequency(e.target.value)}> <option value="WEEKLY">Weekly</option> <option value="BI-WEEKLY">Bi-Weekly</option> <option value="MONTHLY">Monthly</option> <option value="BI-MONTHLY">Bi-Monthly</option> <option value="QUARTERLY">Quarterly</option> <option value="SEMI-YEARLY">Semi-Yearly</option> <option value="ANNUAL">Annual</option> </select> </label> <br /> <button type="submit">Submit</button> </form> <ErrorMsg hasError={isError} /> </React.Fragment> ) }
Flask后端代码错误修复
1. 统一数据获取方式:去掉request.form,只用request.get_json()
前端发送JSON格式数据,后端需统一用request.get_json()解析,不能混用request.form(后者用于解析表单编码数据)。
2. 修正参数名:term → frequency
前端表单下拉框的name属性是frequency,后端错误使用term作为参数名,导致无法获取对应值。
修复后的Flask代码
from datetime import date, datetime, timedelta import holidays from flask import Flask, jsonify, request from flask_cors import CORS app = Flask(__name__) term_dict = { "WEEKLY": 7, "BI-WEEKLY": 14, "MONTHLY": 30, "BI-MONTHLY": 60, "QUARTERLY": 90, "SEMI-YEARLY": 180, "ANNUAL": 365 } @app.get('/test_endpoint') def test_endpoint(): return {"members" : ["1", "2","3"]} @app.post('/get_dates') def frequency_dates(): data = request.get_json() if not data: return jsonify({'error': 'No data received'}), 400 # 统一用request.get_json()获取所有参数 start_date = datetime.strptime(data['start_date'], '%Y-%m-%d').date() end_date = datetime.strptime(data['end_date'], '%Y-%m-%d').date() term = data['frequency'] # 修正参数名 if term not in term_dict: return jsonify({'error': 'Invalid term'}), 400 frequency_dates = [] delta_days = term_dict[term] current_date = start_date while current_date <= end_date: frequency_dates.append(str(current_date)) current_date += timedelta(days=delta_days) return jsonify({'frequency_dates': frequency_dates}), 200 @app.route('/is_us_holiday', methods=['POST']) def is_us_holiday(): input_date = datetime.strptime(request.form['input_date'], '%Y-%m-%d').date() us_holidays = holidays.country_holidays('US') nyse_holidays = holidays.financial_holidays('NYSE') is_holiday = input_date in us_holidays or input_date in nyse_holidays return jsonify({'is_holiday': is_holiday}), 200 cors = CORS(app, resources={'/*':{'origins': 'http://localhost:3000'}}) if __name__ == "__main__": app.run(debug=True) # 开启debug模式方便排查错误
额外提示
- 开启Flask的
debug=True可实时查看错误详情,便于调试 - React组件命名需首字母大写,否则会被识别为普通HTML标签
- 使用
async/await替代Promise链,代码可读性更强
内容的提问来源于stack exchange,提问作者James Miller
相关产品推荐
相关产品推荐

