【问题标题】:OnClick fires for another buttons click eventOnClick 触发另一个按钮单击事件
【发布时间】:2021-12-21 14:53:25
【问题描述】:

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

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;

这是上面代码的控制器。

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;

小按钮

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;

【问题讨论】:

  • 你能显示&lt;SmallButton&gt;的代码吗?它实际上是否将type 传递给底层&lt;button&gt; 元素? type 在 HTML 中的默认值是 "submit",这将使表单内的任何按钮都提交它,除非该类型设置正确。
  • 我在上面添加了 SmallButton 代码
  • 尝试将两个SmallButton组件移出密码&lt;label&gt;元素。
  • 当我将 smallButtons 移出
  • 我创建了一个代码沙盒,代码为codesandbox.io/s/react-playground-forked-sm6vl?file=/…,取消按钮不会按预期恢复到点击时的原始视图。您可以在那里查看日志,似乎由于某种原因 disableButtons 单击事件正在触发。不知道为什么

标签: reactjs react-hooks next.js


【解决方案1】:

TL;DR

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

详细解释

转到您发布的沙盒。它以显示模式(不是编辑模式)打开。现在,按顶部的文本“管理员”。如您所见,“禁用帐户”按钮被按下 - 肯定不是预期的行为。

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

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

【讨论】:

    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 2011-04-03
    • 2020-05-01
    • 2014-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多