Next.js项目中点击取消按钮触发disableAccount按钮onClick事件问题
问题根源
这个异常是HTML <label> 标签的默认行为和React重渲染逻辑共同作用导致的:
- 你把整个表单和所有按钮都嵌套在了最外层的
<label>标签内部,<label>标签的原生默认行为是:点击标签区域时,会自动触发标签内部关联的可交互元素(比如按钮、输入框)的点击事件。 - 点击取消按钮时,首先执行取消按钮的回调将
isEditMode设为false,触发组件重渲染,编辑态的内容会被替换为非编辑态的「禁用账户」按钮。此时外层<label>的点击事件还在传播,会自动触发刚渲染出来的「禁用账户」按钮的点击事件,把isEditMode又重新设为true,最终看起来就像点击取消没有生效。
修复方案
只需要修改 DisableAccountForm 组件的最外层容器即可:把原本作为容器的 <label> 标签替换为普通的 <div> 标签,不需要改变其他逻辑,就能完全解决问题。
修改后的代码片段如下:
import React from 'react'; import TextInput from '../Input/TextInput'; import SmallButton from '../Buttons/SmallButton'; const DisableAccountForm = ({t, tc, onSubmit, password, setPassword, isEditMode, setIsEditMode}) => { // 仅把最外层的label替换为div即可 return ( <div className="block w-full max-w-xl text-2xl mb-4"> {t("admin")} <form onSubmit={onSubmit} className="w-full max-w-xl text-base mt-2"> <p className="mb-4"> {t("disableP")} </p> {isEditMode ? <div> <p className="mb-4"> {t("youSureP")} </p> <p className="text-sm mb-4"> {t("enterPasswordP")} </p> </div> : null } {isEditMode ? <label className="flex-col"> {tc("password")} <TextInput placeholder={tc("password")} value={password} onChange={e=>setPassword(e.target.value)} style="m-1" required /> <SmallButton type="submit" label={tc("submit")} color='bg-blue-500' textColor='text-white' /> <SmallButton type="button" label={tc("cancel")} color='bg-red-500' textColor='text-white' onClick={() => {console.log("cancel"); setIsEditMode(false)}} /> </label> : <SmallButton type="button" label={t("disableAccount")} color='bg-blue-500' textColor='text-white' onClick={() => {console.log("why"); setIsEditMode(true)}} /> } </form> </div> ); } export default DisableAccountForm;
可选优化
你代码里包裹密码输入框和提交、取消按钮的 <label> 也不符合HTML语义规范,同样建议换成 <div>,只给密码提示文本单独加关联输入框的 <label> 即可,避免后续再出现类似的事件触发异常。
内容的提问来源于stack exchange,提问作者Kristian Martinez
相关产品推荐
相关产品推荐

