为什么里面有输入的标签会导致onClick运行2次?

const { StrictMode } = React;
const { createRoot } = ReactDOM;

function App() {
  return (
    <label className="label" onClick={()=> console.log("label onClick")}>
      <input className="radio" type="radio" />
    </label>
  );
}

const root = createRoot(document.getElementById("root"));
root.render(<StrictMode><App /></StrictMode>);
.label {
  display: block;
  background-color: red;
  width: 300px;
  height: 100px;
  position: relative;
}

.radio {
  width: 30px;
  height: 30px;
}
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<div id="root"></div>

推荐答案

comment above倍的 @M0ns3R:

根据documentation,"当用户点击或touch /轻击标签时,浏览器将焦点转移到与其相关的输入(结果事件也会针对该输入引发)".我想这就是为什么.

并且event propagation(react.dev docs)是label元素上onClick事件中的double calls个的原因.

以下是发生的情况(by 100):

  1. 点击label呼叫其onClick
  2. 然后它在第一个(从上到下)input元素上触发100
  3. 该事件冒泡到其父事件(100),并重新调用其onClick(2nd time).

防止默认冒泡阶段的一种方法是将onClick传递给第一个input元素并在其回调调用e.stopPropagation内.

CodeSandbox上的代码:

Edit polished-morning-7dlfxs

(要证明这一点,您可以复制inputwithout an 101中的一个,并将其粘贴到inputwithonClick的上方,然后亲自查看点击label Now again会触发onClick两次.)

第二种方式(I left it commented out, so you can uncomment & test)是简单地在label‘S onClick事件处理程序函数内调用e.preventDefault().现在你可以remove第一个input‘S onClick,并看到两个呼叫已经被修复.

Reactjs相关问答推荐

如何将google地址lat收件箱设置为输入值?

Reaction Native:在初始获取后,Reducer变为未定义

react 副作用循环

通过单击具有此值的按钮将值添加到数组对象键

如何在react 流中使用文本区域和改变 node 的输入大小?

生成Reaction Vite应用程序的停靠容器时无法识别环境变量

为什么react日历时间轴项Renderprops 不能与useState挂钩一起使用?

useEffect firebase 清理功能如何工作?

如何将 MUI X 数据网格单元格方向更改为行级而不是列级?

如何在 React Hook Form 中使用嵌套对象处理错误验证消息

如何在 React 中停止嵌套 Link 和 Button 组件的事件传播?

如何在 ReactJS 中提交后删除 URL 中的查询参数

将props 传递给 NextJS 布局组件

来自一个自定义 React Native 组件的样式从另一个自定义组件移除样式

React JS:如何判断用户使用的是浏览器 url 还是桌面 electron

React Router v6 - 访问嵌套路由和处理手写 url 的正确方法

组件焦点上的 MUI 更改栏 colored颜色

试图将页面限制为仅登录但有条件的用户似乎永远不会运行

RTK 查询 POST 方法不会改变数据

如何判断对话框组件是否位于对话框之上?