ReactJS表单多submit按钮点击后value为undefined的问题如何解决
问题根因
- 事件目标指向错误:点击按钮时如果点到内部的
<span>或<FontAwesomeIcon>子元素,event.target会指向子元素而非按钮本身,子元素没有设置value属性,因此拿到undefined。 - 状态更新异步:React中
setState是异步操作,onClick触发的状态更新可能晚于表单onSubmit事件的执行,导致saveEntity调用filteredEntities时,buttonClick还没完成更新,仍然是初始值。
解决方案
方案1:直接利用表单提交事件的submitter属性(最推荐)
现代浏览器都支持Event.submitter属性,会直接返回触发本次表单提交的按钮元素,不需要单独绑定点击事件存储状态,从根源避免异步和事件目标错误问题。
修改代码如下:
// 去掉两个Button上的onClick={buttonClicked}属性,无需该函数 const saveEntity = (event, errors, values) => { // 直接从原生提交事件获取触发提交的按钮,取value const submitType = event.nativeEvent.submitter?.value; // 可选增加兜底逻辑,避免异常情况 if (!submitType) { console.warn('未识别的提交操作'); return; } filteredEntities(params, sorting, submitType); } // filteredEntities新增参数接收提交类型,不再依赖state const filteredEntities = (params, sort, submitType) => { console.log('-- 提交类型 --', submitType); if (submitType === 'pdf') { getReportPDF(params, sort); } if (submitType === 'csv') { getReportCSV(params, sort); } }
注:如果需要兼容IE等不支持
submitter属性的老旧浏览器,优先选用方案2。
方案2:修复原有逻辑的问题
如果需要保留原有onClick的写法,修改两个点即可:
- 点击事件中用
event.currentTarget代替event.target,currentTarget永远指向绑定事件的元素,也就是按钮本身,不会受点击子元素的影响 - 用ref存储点击类型,ref赋值是同步的,不存在状态更新延迟的问题
修改代码如下:
import { useRef } from 'react'; // 声明ref存储按钮点击类型,初始值设为空 const buttonClickRef = useRef(''); const buttonClicked = event => { // 用currentTarget取绑定事件的按钮元素 const clickValue = event.currentTarget.value; console.log('event target', clickValue); buttonClickRef.current = clickValue; }; const filteredEntities = (params, sort) => { // 从ref中取值,是实时同步的 const buttonClick = buttonClickRef.current; console.log('-- buttonClick --', buttonClick); if (buttonClick === 'pdf') { getReportPDF(params, sort); } if (buttonClick === 'csv') { getReportCSV(params, sort); } // 操作完成后清空ref,避免下次提交误用旧值 buttonClickRef.current = ''; }
内容的提问来源于stack exchange,提问作者Jack23
相关产品推荐
相关产品推荐

