hellof2e / quark-design

Browser-native component library, framework-agnostic, base on web components.(移动端 UI 组件库,无框架,即插即用。)
https://quark-ecosystem.github.io/quarkd-docs
MIT License
1.9k stars 189 forks source link

[按钮] 设置事件会重复执行 #56

Closed lx-summer closed 1 year ago

lx-summer commented 1 year ago

Quark Design 版本

1.0.12

重现链接

No response

重现步骤

import React, { useState } from 'react'; import { Button } from '@quarkd/quark-react'; // import { Button } from 'antd';

const Index = () => { const [count, setCount] = useState(0); console.log(count); return (

); };

export default Index;

期望结果

1

实际结果

2

框架版本

react

浏览器版本

No response

系统版本

No response

Node版本

No response

补充说明

No response

Maidang1 commented 1 year ago
image

研究了一下 不明白为啥 update 两次,坐等官方解释一手

vaakian commented 1 year ago

这是 React 18 之后在开发模式时故意渲染的两次,防止你忘记清除副作用(side-effect,比如addEventListener就是一个副作用)。

解决办法:

参考: https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects https://zh-hans.reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects https://www.google.com/search?q=react+18+double+render

Maidang1 commented 1 year ago

但是好像影响到了外面,导致 onclick 事件执行了两次,点击数字就从 0 变成了 2

vaakian commented 1 year ago

我试了一下,按钮事件被调用2次 确实是一个Bug, 不属于React 18 的2次渲染的正常原因(只有生命周期渲染的2次是)。

问题应该就出在 reactifyWebComponent 上了🤔。

vaakian commented 1 year ago

尝试将下面的行删除掉就正常了:

https://github.com/hellof2e/quark-design/blob/a4c4b7f0b538b2d723a98c0809b156cbff154899/packages/quark-reactify/src/index.ts#L22

所以应该是: 在props透传给原生web-component的时候就已经注册了一次事件,然后自己又手动注册了一次。

https://github.com/hellof2e/quark-design/blob/a4c4b7f0b538b2d723a98c0809b156cbff154899/packages/quark-reactify/src/index.ts#L63

Maidang1 commented 1 year ago

尝试将下面的行删除掉就正常了:

https://github.com/hellof2e/quark-design/blob/a4c4b7f0b538b2d723a98c0809b156cbff154899/packages/quark-reactify/src/index.ts#L22

所以应该是: 在props透传给原生web-component的时候就已经注册了一次事件,然后自己又手动注册了一次。

https://github.com/hellof2e/quark-design/blob/a4c4b7f0b538b2d723a98c0809b156cbff154899/packages/quark-reactify/src/index.ts#L63

一会我再调试一下 已经理解你的意思了 👍

vaakian commented 1 year ago

已经确定Bug逻辑了:

所以这里需要做一个列表判断,是否是属于原生事件,或者干脆函数把类型的 prop 不透传到 createElement(但太一刀切了)。

sanqi-med commented 1 year ago

@vaakian 你的理解是对的,这边暂时针对click事件已经做了过滤处理了,组件暂时还未使用到其它原生事件,后期如果有其它事件会做个列表判断,或者你那边也可以提PR哈。

sanqi-med commented 1 year ago

已修复

Maidang1 commented 1 year ago

@vaakian 你的理解是对的,这边暂时针对click事件已经做了过滤处理了,组件暂时还未使用到其它原生事件,后期如果有其它事件会做个列表判断,或者你那边也可以提PR哈。

这样只针对 click 判断也有问题吧 注册了鼠标事件也是一样的吧

CVopen commented 1 year ago

@vaakian你的理解是判断对其他其他此类事件的点击已经进行了过滤处理,某些事件,有时可能会使用到某个事件,如果有事件会做个列表,或者你也提提 PR 。

image image

鼠标和键盘事件同样会执行两次,Field组件聚焦和失焦事件同样也会执行两次

sanqi-med commented 1 year ago

quark 组件目前使用的原生事件三个: click、 blur、 focus、这三个事件已经做了filter。其它原生事件组件内部并未使用,使用quark 组件哪种场景需要再传额外的原生事件呢