iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >AntDesign的Bug修复示例详解
  • 885
分享到

AntDesign的Bug修复示例详解

AntDesignBug修复AntDesignBug 2022-11-13 18:11:02 885人浏览 独家记忆
摘要

目录引言第一步、选择要修复的Bug第二步、准备工作第三步、问题排查第四步、问题修复第五步、单元测试第六步、提交Pull Request总结引言 我在工作中大量使用Ant Design

引言

我在工作中大量使用Ant Design,它为我省去了很多重复劳动,所以有空的时候,我也会为Ant Design做一些微小的贡献。

本文详细描述了我处理一个Ant Design的Bug全过程,文章内容较多但难度并不高,新手同学看完也可以尝试为Ant Design添砖加瓦!

第一步、选择要修复的Bug

Ant Design有不少Bug,你可以直接访问它的Issues,挑一个简单的问题尝试解决,需要注意的是,并不是所以Issue都是Bug,经过管理员确认过的Bug一般会打上Bug的标记。

这次我处理的问题是#37165。

第二步、准备工作

Fork ant-design仓库到自己的GitHub,回到自己的github,将刚刚Fork的仓库克隆到本地,然后基于master分支新建一个bugfix分支,接着安装依赖,启动项目,然后就可以在开发环境访问Ant Design官网上所有的Demo,方便调试。

npm install && npm run start

第三步、问题排查

回到问题#37165,它的表现是:一个DatePicker,一个Input, 用户用鼠标选中Input的内容进行复制时经常会滑到DatePicker,会触发日历控件输入框的focus事件。

这种操作是比较常见的,问题简化完了就是:只要在日历控件上触发mouseUp就会打开日历控件。

查看官网Demo发现确实存在这个问题,第一反应是日历控件的输入框绑定了onMouseUp事件,查看对应的DatePicker组件源码,定位到文件ant-design/components/date-picker/generatePicker/generateSinglePicker.tsx第121~156行

(基于antd@4.23.4版本,不同版本行数可能不同):

import RCPicker from 'rc-picker';
// 中间代码省略……
<RCPicker<DateType>
  ref={innerRef}
  placeholder={getPlaceholder(mergedPicker, locale, placeholder)}
  suffixIcon={suffixnode}
  dropdownAlign={transPlacement2DropdownAlign(direction, placement)}
  dropdownClassName={popupClassName || dropdownClassName}
  clearIcon={<CloseCircleFilled />}
  prevIcon={<span className={`${prefixCls}-prev-icon`} />}
  nextIcon={<span className={`${prefixCls}-next-icon`} />}
  superPrevIcon={<span className={`${prefixCls}-super-prev-icon`} />}
  superNextIcon={<span className={`${prefixCls}-super-next-icon`} />}
  allowClear
  transitionName={`${rootPrefixCls}-slide-up`}
  {...additionalProps}
  {...restProps}
  {...additionalOverrideProps}
  locale={locale!.lang}
  className={classNames(
    {
      [`${prefixCls}-${mergedSize}`]: mergedSize,
      [`${prefixCls}-borderless`]: !bordered,
    },
    getStatusClassNames(
      prefixCls as string,
      getMergedStatus(contextStatus, customStatus),
      hasFeedback,
    ),
    className,
  )}
  prefixCls={prefixCls}
  getPopupContainer={customizeGetPopupContainer || getPopupContainer}
  generateConfig={generateConfig}
  components={Components}
  direction={direction}
  disabled={mergedDisabled}
/>

以上源码没有传入onMouseUp,将解构赋值prop的{...restProps}注释掉,查看本地Demo,问题依然存在,说明restProps也没有传入onMouseUp

由于DatePicker组件是基于RCPicker封装的,接下来继续深入RCPicker组件,看看onMouseUp是不是在RCPicker里面绑定的。

rc-pickerReact-components组件库中的日历组件,Ant Design大部分组件都是在react-components基础上封装的。

查看rc-picker源码,rc-picker默认导出的是Picker组件:

import Picker from './Picker';
//...
export default Picker;

定位到picker/src/Picker.tsx,搜索字符串"onMouseUp",发现在日历控件输入框的父级div绑定了onMouseUp事件,对应的回调函数在287行(基于rc-picker@2.6.10):

// 输入框父级元素 L530~L555
<div
  ref={containerRef}
  className={classNames(prefixCls, className, {
    [`${prefixCls}-disabled`]: disabled,
    [`${prefixCls}-focused`]: focused,
    [`${prefixCls}-rtl`]: direction === 'rtl',
  })}
  style={style}
  onMouseDown={onMouseDown}
  // 看这里
  onMouseUp={onInternalMouseUp}
  onMouseEnter={onMouseEnter}
  onMouseLeave={onMouseLeave}
  onContextMenu={onContextMenu}
  // 顺便关注一下这里,后文会说
  onClick={onClick}
>
  <div
    className={classNames(`${prefixCls}-input`, {
      [`${prefixCls}-input-placeholder`]: !!hoverValue,
    })}
    ref={inputDivRef}
  >
    {inputNode}
    {suffixNode}
    {clearNode}
  </div>
</div>
// onMouseUp回调 L287~L296
const onInternalMouseUp: React.MouseEventHandler<htmlDivElement> = (...args) => {
  if (onMouseUp) {
    onMouseUp(...args);
  }
  // 问题就在这里
  if (inputRef.current) {
    inputRef.current.focus();
    triggerOpen(true);
  }
};

就在函数onInternalMouseUp中,除了触发onMouseUp,还触发了输入框的focus事件!

if (inputRef.current) {
  inputRef.current.focus();
  triggerOpen(true);
}

此时,应该弄清楚一件事:当时为什么要写这几行代码?

最好的途径就是看看当时的commit message,为了方便后续调试,还是将rc-picker仓库克隆到本地:先Fork,再新建分支,然后安装依赖,启动项目。

PS:vscode安装GitLens插件,即可查看每一行代码的commit记录。

从这几行代码对应的commit了解到,这几行代码是为了解决Ant Design的日历控件点击输入框右侧的icon没有弹出日历面板的问题。

知道它的作用了,已经成功了一半!看看要怎么修复?

第四步、问题修复

到这一步,建议先到对应的Issue下面留言说明正在处理中,避免其他开发者再花时间修复同一个问题。

接着,要解决2个问题:

  • 点击日历控件输入框右侧的icon需要打开日历面板
  • 不要用mouseUp事件来打开,想想其它实现方式

答案显而易见了,那就是改成在onClick里触发,因为icon节点同样被输入框的父级包裹,icon的click事件必然会冒泡到父级,从而触发父级的onClick。

查看以上源码发现,输入框的父级已经有一个onClick属性,只需要将以上的4行代码挪到onClick的回调即可,点击这里查看详细修改。

修改完成,查看本地Demo,问题已经解决了,胜利在望!

第五步、单元测试

原来的commit写了对应的单元测试,我们修改了它的实现,同时也需要修改对应的单元测试:

// picker/tests/picker.spec.tsx L620~631
it('Picker should open when click inside', () => {
  const onClick = jest.fn();
  const wrapper = mount(<MomentPicker onClick={onClick} />);
  const inputElement = wrapper.find('input').instance() as any as HTMLInputElement;
  inputElement.focus = jest.fn();
  wrapper.find('.rc-picker').simulate('click');
  expect(inputElement.focus).toHaveBeenCalled();
  expect(wrapper.isOpen()).toBeTruthy();
  expect(onClick).toHaveBeenCalled();
});

修改完成之后,完整地跑一遍单元测试:

npm run test

确保所有单元测试都通过

Test Suites: 8 passed, 8 total
Tests:       294 passed, 294 total
Snapshots:   11 passed, 11 total
Time:        15.643s

代码部分到这里就算圆满完成了!

第六步、提交Pull Request

这一步,是本文最简单的一步了!

提交代码,push到远程仓库,打开仓库页面,会看到页面上出现了一个【compare & pull request】的入口,点击即可向Ant Design创建合并请求,输入修复的Issue链接(这个很重要,到时候Issue页面会自动关联你的此次的pull request)和修复思路或理由,方便管理员review。

最后,等待管理员review,没问题的话管理员会合并分支,然后发布新版本,代码最终会应用到数十万项目中,Bug修复大功告成!

总结

最后,总结一下,第一次提交PR,建议选择简单的Issue,重要的是先将整个流程熟悉一遍,不要一开始就挑战复杂的问题,如果花了很长时间却解决不了问题,自信心受挫,可能就不想继续下去了。

以上就是Ant Design 的Bug修复示例详解的详细内容,更多关于Ant Design Bug修复的资料请关注编程网其它相关文章!

--结束END--

本文标题: AntDesign的Bug修复示例详解

本文链接: https://www.lsjlt.com/news/170285.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • AntDesign的Bug修复示例详解
    目录引言第一步、选择要修复的Bug第二步、准备工作第三步、问题排查第四步、问题修复第五步、单元测试第六步、提交Pull Request总结引言 我在工作中大量使用Ant Design...
    99+
    2022-11-13
    Ant Design Bug修复 Ant Design Bug
  • Apache SkyWalking 修复TTL timer 失效bug详解
    目录正文SkyWalking OAP 角色SkyWalking OAP 集群Data TTL timer 配置DataTTLKeeperTimer 定时任务Bug 产生的原因解决 B...
    99+
    2024-04-02
  • JDK序列化Bug难题解决示例详解
    目录1、背景2、分析3、复现4、解决总结1、背景 最近查看应用的崩溃记录的时候遇到了一个跟 Java 序列化相关的崩溃, 从崩溃的堆栈来看,整个调用堆栈里没有我们自己的代码信息。...
    99+
    2023-03-19
    JDK序列化Bug解决 JDK序列化
  • RocketMQ实现随缘分BUG小功能示例详解
    目录正文实现过程生产者:正文 以前公司的产品已经上线20多年了,主要是维护,也就是改bug。每周我们Team会从Jira上拿我们可以改的bug,因为每个团队负责的业务范围不一样,我们...
    99+
    2022-11-13
    RocketMQ随缘BUG RocketMQ BUG
  • Android热修复及插件化原理示例详解
    目录1.前言2.类加载机制3.Android类加载4.Tinker原理代码实现5.插件化5.1 Activity启动流程简单介绍5.2 插件化原理5.2.1 绕开验证5.2.2还原插...
    99+
    2022-11-13
    Android热修复插件化 Android热修复
  • Redisexists命令bug分析(案例详解)
    目录1、复现条件版本:2、源码分析3、问题解决本文基于社区版Redis 4.0.8 1、复现条件版本: 社区版Redis 4.0.10以下版本使用场景:开启读写分离的主从架构或者集群...
    99+
    2024-04-02
  • Pytorch复现扩散模型的示例详解
    目录开发环境1 加载相关第三方库2 加载数据集3 确定超参数的值5 演示原始数据分布加噪100步后的效果6 编写拟合逆扩散过程高斯分布的模型7 ...
    99+
    2023-05-17
    Pytorch复现扩散模型 Pytorch扩散模型 Pytorch 扩散
  • 如何修复Fedora Linux 中Bug以及确定Bug的优先级
    今天就跟大家聊聊有关如何修复Fedora Linux 中Bug以及确定Bug的优先级,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。发布开发过程作为一个 Linux 发行项目,我们希望...
    99+
    2023-06-15
  • Android 手写热修复dex实例详解
    目录现有的热修复框架很多,尤以AndFix 和Tinker比较多今天就来探讨,如何手写一个热修复的功能什么是双亲委托机制话不多说,提出了解决方法,下面着手去实现总结现有的热修复框架很...
    99+
    2023-03-06
    Android 手写热修复dex Android dex
  • Redis全量复制与部分复制示例详解
    Redis 主从复制 Redis 实例划分为主节点(master)和从节点(slave) 默认情况下,Redis都是主节点 每个从节点只能有一个主节点,而主节点可以同时具有多个从节点 复...
    99+
    2024-04-02
  • Python实现强制复制粘贴的示例详解
    目录前因后果流程思路代码展示效果展示前因后果 公司有人阳了,今天在家上班,突然小姨子就问我有没有baidu文库会员,想下载点东西,我心想这还要会员?用Python不是分分钟的事情! ...
    99+
    2022-12-19
    Python强制复制粘贴 Python 复制粘贴
  • win7系统修复的示例分析
    小编给大家分享一下win7系统修复的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!点击开始菜单,在搜索框中输入CMD。在搜索结果中找到CMD程序,右键点击...
    99+
    2023-06-28
  • git怎么修改origin地址?示例详解
    在使用 Git 进行协作开发的过程中,我们经常需要修改远程仓库的地址。对于 Git 而言,每一个远程仓库都是一个 Git 服务器的地址,这个地址被称为 origin。一般情况下,我们需要修改 origin 的地址来连接不同的 Git 服务器...
    99+
    2023-10-22
  • MySQL-JDBC驱动引起bug问题的示例
    这篇文章给大家分享的是有关MySQL-JDBC驱动引起bug问题的示例的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。问题背景公司是做电商系统的,整个系统搭建在华为云上。系统设计的...
    99+
    2024-04-02
  • C++多态的示例详解
    目录案例一:计算器案例要求代码实现运行效果案例二:制作饮品案例要求代码实现运行效果案例三:电脑组装案例要求代码实现运行效果今天就以三个案例来把C++多态的内容结束。第一个案例就是用多...
    99+
    2024-04-02
  • React18中的useDeferredValue示例详解
    目录有什么用?实操起来跟防抖的区别 接着上一篇React18的简介和自动批处理的特性,今天我们来聊下useDeferredValue。 有什么用? lets you defer up...
    99+
    2024-04-02
  • react-redux的connect示例详解
    connect简介:connect是react-redux两个api中其中之一,在使用react-redux时起到了为redux中常用的功能实现了和react连接的建立函数入口,以及...
    99+
    2023-01-31
    react-redux的connect react-redux
  • JavaScript中的FileReader示例详解
    目录前言:input:fileFileReader补充:一个比较全面的例子总结前言: FileReader是一种异步文件读取机制,结合input:file可以很方便的读取本地文件。 ...
    99+
    2024-04-02
  • JavaHttpClient用法的示例详解
    目录1、导入依赖2、使用工具类3、扩展1、导入依赖 <dependency> <groupId>org.apache.httpcomponents&l...
    99+
    2024-04-02
  • JS实现可恢复的文件上传示例详解
    目录正文不太实用的进度事件算法server.jsuploader.jsindex.html正文 使用 fetch 方法来上传文件相当容易。 连接断开后如何恢复上...
    99+
    2022-12-29
    JS恢复文件上传 JS文件恢复
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作