OnClick 触发另一个按钮单击事件 [英] OnClick fires for another buttons click event

查看:24
本文介绍了OnClick 触发另一个按钮单击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某种原因,在我的代码中,每当我单击取消按钮时,disableAccount 按钮的 onClick 事件就会被激活.因此,取消将 isEditMode 设置为 false,但 disableAccount 将其设置回 true,从而阻止我在 UI 中看到任何明显的变化.这是一个 next.js 项目.

从'react'导入反应;从'../Input/TextInput'导入TextInput;从../Buttons/SmallButton"导入 SmallButton;const DisableAccountForm = ({t, tc, onSubmit, 密码, setPassword, isEditMode, setIsEditMode}) =>{返回 (<label className="block w-full max-w-xl text-2xl mb-4">{t(管理员")}<form onSubmit={onSubmit} className="w-full max-w-xl text-base mt-2><p className="mb-4">{t(禁用P")}</p>{是编辑模式?

<p className="mb-4">{t(youSureP")}</p><p className="text-sm mb-4">{t("enterPasswordP")}</p></div>: 空值}{是编辑模式?<label className="flex-col">{tc(密码")}<文本输入占位符={tc(密码")}值={密码}onChange={e=>setPassword(e.target.value)}样式=m-1";必需的/><小按钮类型=提交";标签={tc(提交")}颜色='bg-蓝色-500'textColor='文本-白色'/><小按钮类型=按钮";标签={tc(取消")}颜色='bg-red-500'textColor='文本-白色'onClick={() =>{console.log(取消");setIsEditMode(false)}}/></标签>:<小按钮类型=按钮";标签={t("disableAccount")}颜色='bg-蓝色-500'textColor='文本-白色'onClick={() =>{console.log(为什么");setIsEditMode(true)}}/>}</表格></标签>);}导出默认 DisableAccountForm;

这是上面代码的控制器.

import React, {useState} from 'react';从../components/DisableAccountForm/DisableAccountForm"导入 DisableAccountForm;const DisableAccountController = ({t, tc, onSubmit}) =>{const [密码, setPassword] = useState("");const [isEditMode, setIsEditMode] = useState(false);const disableAccount = (e) =>{e.preventDefault();console.log("disableAccount");setIsEditMode(false);}返回 (

小按钮

从'react'导入反应;const SmallButton = ({type, label, color, textColor, style, onClick}) =>{返回 (<按钮类型={类型}className={`m-1 ${color} hover:ring-2 rounded-md px-2 py-1 min-w-20 ${textColor} ${style}`}onClick={onClick}>{标签}</按钮>);}导出默认 SmallButton;

解决方案

TL;DR

问题在于 label 包装器点击";在表单从编辑模式切换到显示模式后立即禁用帐户按钮.这是 HTML label 元素的默认行为.您可以通过将 label 更改为 div 或片段或任何其他不单击按钮的包装器来解决它.

详细解释

转到您发布的沙盒.它以显示模式(不是编辑模式)打开.现在,按文本Admin";在顶端.如您所见,禁用帐户"按钮被按下 - 肯定不是预期的行为.

发生这种意外行为的原因与取消按钮切换回编辑模式的原因相同.整个问题是关于包装表单的 label .HTML 原生 label 元素label 附近或内部的可点击元素之一的点击事件附加到 label 内部的内容.在显示模式下,label 检测到禁用帐户";按钮并将其单击事件附加到整个组件.

因此,当您单击取消"时按钮 - 组件切换到编辑模式,label 包装器点击";禁用帐户"按钮并将其切换回编辑模式.提交表单时您看不到它,因为您在 onSubmit 回调中阻止了 label 的默认行为.您的问题的部分解决方案也可以是 preventDefault 在取消回调中 - 但它会使文本可点击.另一种解决方案可能是将 label 更改为 div 或片段或任何其他不单击按钮的包装器.

For some reason, in my code the onClick event for the disableAccount button gets activated whenever I click the cancel button. So cancel sets isEditMode to false but disableAccount sets it back to true thus preventing me from seeing any noticeable change in my UI. This is a next.js project.

import React from 'react';
import TextInput from '../Input/TextInput';
import SmallButton from '../Buttons/SmallButton';

const DisableAccountForm = ({t, tc, onSubmit, password, setPassword, isEditMode, setIsEditMode}) => {
  return (
    <label 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>
    </label>
  );
}

export default DisableAccountForm;

This is the controller for the code above.

import React, {useState} from 'react';
import DisableAccountForm from '../components/DisableAccountForm/DisableAccountForm';

const DisableAccountController = ({t, tc, onSubmit}) => {
  const [password, setPassword] = useState("");
  const [isEditMode, setIsEditMode] = useState(false);

  const disableAccount = (e) => {
    e.preventDefault();
    console.log("disableAccount");
    setIsEditMode(false);
  }

  return (
    <DisableAccountForm 
    t={t}
    tc={tc}
    onSubmit={disableAccount}
    password={password}
    setPassword={setPassword}
    isEditMode={isEditMode}
    setIsEditMode={setIsEditMode}
    />
  );
}

export default DisableAccountController;

SmallButton

import React from 'react';

const SmallButton = ({type, label, color, textColor, style, onClick}) => {
  return (
    <button 
      type={type} 
      className={`m-1 ${color} hover:ring-2 rounded-md px-2 py-1 min-w-20 ${textColor} ${style}`}
      onClick={onClick}
    >
      {label}
    </button>
  );
}

export default SmallButton;

解决方案

TL;DR

The problem is that the label wrapper "clicks" the Disable account button right after the form is switched from edit to display mode. It is the default behaviour of HTML label elements. You can solve it by changing the label to div or fragment or any other wrapper that does not click your buttons.

Explain In Details

Go to the sandbox you have posted. It opens in display mode (not edit mode). Now, press the text "Admin" on the top. As you can see, the "Disable account" button is pressed - surely not the expected behaviour.

This unexpected behaviour happens for the same reason that the cancel button switches back to edit mode. the whole problem is about the label that wraps the form. The HTML native label element attaches the click event of one of the clickable elements nearby or inside the label to the content inside the label. In-display mode, the label detect the "Disable account" button and attach its click event to the whole component.

So, when you click the "cancel" button - the component switches to edit mode, and the label wrapper "clicks" the "Disable account" button and switches it back to edit mode. You don't see it when submitting the form, because you prevent the label's default behaviour in onSubmit callback. A partial solution for your problem can be to preventDefault in the cancel callback too - but it will leave the texts clickable. Another solution might be to change the label to div or fragment or any other wrapper that does not click your buttons.

这篇关于OnClick 触发另一个按钮单击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆