OnClick 触发另一个按钮单击事件

IT技术 reactjs react-hooks next.js
2021-05-16 15:58:12

出于某种原因,在我的代码中,每当我单击取消按钮时onClickdisableAccount按钮事件就会被激活。因此取消设置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;
1个回答

TL; 博士

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

详细解释

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

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

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