React中type为submit的删除按钮未触发onSubmit事件问题
问题分析
点击Update按钮时,updateItem执行后能正常触发handleSubmit,但点击Remove按钮时,只有removeItem执行,handleSubmit没触发。核心原因是:
- Remove按钮的
onClick会删除当前列表项,React会立即重新渲染,对应<li>元素被卸载,导致后续的表单提交事件因为触发元素已不存在而被中断。 - Update按钮只是修改列表项的属性,组件不会被卸载,所以提交事件能完整执行。
解决方案
这里提供两种可行的解决思路:
思路一:延迟状态更新,让提交事件先执行
把删除操作放到setTimeout里,让表单提交事件先完成,再执行删除:
const removeItem = (id: number) => { // 用setTimeout把状态更新放到下一轮事件循环,确保submit先触发 setTimeout(() => { setItems(items.filter((item) => item.id !== id)); }, 0); };
思路二:统一在submit事件中处理状态更新
把按钮的操作逻辑移到handleSubmit里,避免因组件卸载中断事件流:
- 修改按钮,添加标识属性区分操作类型
- 在
handleSubmit中根据标识执行对应逻辑
修改后的完整代码:
import React, { useState } from "react"; function MyForm() { const [items, setItems] = useState([ { id: 1, name: "item1" }, { id: 2, name: "item2" }, { id: 3, name: "item3" }, ]); const removeItem = (id: number) => { setItems(items.filter((item) => item.id !== id)); }; const updateItem = (id: number) => { setItems( items.map((item) => { if (item.id === id) { return { ...item, name: "test" }; } else { return item; } }) ); }; const handleSubmit = (event: any) => { event.preventDefault(); const target = event.submitter; // 获取触发提交的按钮 const action = target.dataset.action; const id = Number(target.dataset.id); if (action === "update") { updateItem(id); } else if (action === "remove") { removeItem(id); } console.log("submit"); }; return ( <form onSubmit={handleSubmit}> <ul> {items.map((item) => ( <li key={item.id}> {item.name} <button type="submit" data-action="remove" data-id={item.id}> Remove </button> <button type="submit" data-action="update" data-id={item.id}> Update </button> </li> ))} </ul> </form> ); } export default MyForm;
这种方式更符合表单的设计逻辑,所有操作都通过submit事件统一处理,避免了组件卸载导致的事件中断问题。
内容的提问来源于stack exchange,提问作者Young
相关产品推荐
相关产品推荐

