亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Ant Design 的Bug修復(fù)示例詳解

 更新時間:2022年10月27日 15:39:28   作者:Undefined_w  
這篇文章主要為大家介紹了Ant Design 的Bug修復(fù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

我在工作中大量使用Ant Design,它為我省去了很多重復(fù)勞動,所以有空的時候,我也會為Ant Design做一些微小的貢獻。

本文詳細描述了我處理一個Ant Design的Bug全過程,文章內(nèi)容較多但難度并不高,新手同學(xué)看完也可以嘗試為Ant Design添磚加瓦!

第一步、選擇要修復(fù)的Bug

Ant Design有不少Bug,你可以直接訪問它的Issues,挑一個簡單的問題嘗試解決,需要注意的是,并不是所以Issue都是Bug,經(jīng)過管理員確認過的Bug一般會打上Bug的標(biāo)記。

這次我處理的問題是#37165

第二步、準(zhǔn)備工作

Fork ant-design倉庫到自己的Github,回到自己的Github,將剛剛Fork的倉庫克隆到本地,然后基于master分支新建一個bugfix分支,接著安裝依賴,啟動項目,然后就可以在開發(fā)環(huán)境訪問Ant Design官網(wǎng)上所有的Demo,方便調(diào)試。

npm install && npm run start

第三步、問題排查

回到問題#37165,它的表現(xiàn)是:一個DatePicker,一個Input, 用戶用鼠標(biāo)選中Input的內(nèi)容進行復(fù)制時經(jīng)常會滑到DatePicker,會觸發(fā)日歷控件輸入框的focus事件。

這種操作是比較常見的,問題簡化完了就是:只要在日歷控件上觸發(fā)mouseUp就會打開日歷控件。

查看官網(wǎng)Demo發(fā)現(xiàn)確實存在這個問題,第一反應(yīng)是日歷控件的輸入框綁定了onMouseUp事件,查看對應(yīng)的DatePicker組件源碼,定位到文件ant-design/components/date-picker/generatePicker/generateSinglePicker.tsx第121~156行

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

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,將解構(gòu)賦值prop的{...restProps}注釋掉,查看本地Demo,問題依然存在,說明restProps也沒有傳入onMouseUp。

由于DatePicker組件是基于RCPicker封裝的,接下來繼續(xù)深入RCPicker組件,看看onMouseUp是不是在RCPicker里面綁定的。

rc-pickerreact-components組件庫中的日歷組件,Ant Design大部分組件都是在react-components基礎(chǔ)上封裝的。

查看rc-picker源碼,rc-picker默認導(dǎo)出的是Picker組件:

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

定位到picker/src/Picker.tsx,搜索字符串"onMouseUp",發(fā)現(xiàn)在日歷控件輸入框的父級div綁定了onMouseUp事件,對應(yīng)的回調(diào)函數(shù)在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}
  // 順便關(guān)注一下這里,后文會說
  onClick={onClick}
>
  <div
    className={classNames(`${prefixCls}-input`, {
      [`${prefixCls}-input-placeholder`]: !!hoverValue,
    })}
    ref={inputDivRef}
  >
    {inputNode}
    {suffixNode}
    {clearNode}
  </div>
</div>
// onMouseUp回調(diào) L287~L296
const onInternalMouseUp: React.MouseEventHandler<HTMLDivElement> = (...args) => {
  if (onMouseUp) {
    onMouseUp(...args);
  }
  // 問題就在這里
  if (inputRef.current) {
    inputRef.current.focus();
    triggerOpen(true);
  }
};

就在函數(shù)onInternalMouseUp中,除了觸發(fā)onMouseUp,還觸發(fā)了輸入框的focus事件!

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

此時,應(yīng)該弄清楚一件事:當(dāng)時為什么要寫這幾行代碼?

最好的途徑就是看看當(dāng)時的commit message,為了方便后續(xù)調(diào)試,還是將rc-picker倉庫克隆到本地:先Fork,再新建分支,然后安裝依賴,啟動項目。

PS:VSCode安裝GitLens插件,即可查看每一行代碼的commit記錄。

從這幾行代碼對應(yīng)的commit了解到,這幾行代碼是為了解決Ant Design的日歷控件點擊輸入框右側(cè)的icon沒有彈出日歷面板的問題。

知道它的作用了,已經(jīng)成功了一半!看看要怎么修復(fù)?

第四步、問題修復(fù)

到這一步,建議先到對應(yīng)的Issue下面留言說明正在處理中,避免其他開發(fā)者再花時間修復(fù)同一個問題。

接著,要解決2個問題:

  • 點擊日歷控件輸入框右側(cè)的icon需要打開日歷面板
  • 不要用mouseUp事件來打開,想想其它實現(xiàn)方式

答案顯而易見了,那就是改成在onClick里觸發(fā),因為icon節(jié)點同樣被輸入框的父級包裹,icon的click事件必然會冒泡到父級,從而觸發(fā)父級的onClick。

查看以上源碼發(fā)現(xiàn),輸入框的父級已經(jīng)有一個onClick屬性,只需要將以上的4行代碼挪到onClick的回調(diào)即可,點擊這里查看詳細修改。

修改完成,查看本地Demo,問題已經(jīng)解決了,勝利在望!

第五步、單元測試

原來的commit寫了對應(yīng)的單元測試,我們修改了它的實現(xiàn),同時也需要修改對應(yīng)的單元測試:

// 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到遠程倉庫,打開倉庫頁面,會看到頁面上出現(xiàn)了一個【compare & pull request】的入口,點擊即可向Ant Design創(chuàng)建合并請求,輸入修復(fù)的Issue鏈接(這個很重要,到時候Issue頁面會自動關(guān)聯(lián)你的此次的pull request)和修復(fù)思路或理由,方便管理員review。

最后,等待管理員review,沒問題的話管理員會合并分支,然后發(fā)布新版本,代碼最終會應(yīng)用到數(shù)十萬項目中,Bug修復(fù)大功告成!

總結(jié)

最后,總結(jié)一下,第一次提交PR,建議選擇簡單的Issue,重要的是先將整個流程熟悉一遍,不要一開始就挑戰(zhàn)復(fù)雜的問題,如果花了很長時間卻解決不了問題,自信心受挫,可能就不想繼續(xù)下去了。

以上就是Ant Design 的Bug修復(fù)示例詳解的詳細內(nèi)容,更多關(guān)于Ant Design Bug修復(fù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 微信小程序 監(jiān)聽手勢滑動切換頁面實例詳解

    微信小程序 監(jiān)聽手勢滑動切換頁面實例詳解

    這篇文章主要介紹了微信小程序 監(jiān)聽手勢滑動切換頁面實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 解密效果

    解密效果

    解密效果...
    2006-06-06
  • JavaScript前端實用的工具函數(shù)封裝

    JavaScript前端實用的工具函數(shù)封裝

    這篇文章主要為大家介紹了JavaScript前端實用的一些工具函數(shù)的封裝,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • JavaScript高級之自定義異常

    JavaScript高級之自定義異常

    在JavaScript中所有的異常都是Error對象,遇到異常就會拋出一個Error對象,這個對象中包含錯誤的描述信息,通過JavaScript提供的異常處理語句,我們可以用結(jié)構(gòu)化的方式來捕捉發(fā)生的錯誤,讓異常處理代碼與核心業(yè)務(wù)代碼實現(xiàn)分離,需要的朋友可以參考一下
    2021-12-12
  • Canvas如何判斷點在形狀內(nèi)及內(nèi)置API性能詳解

    Canvas如何判斷點在形狀內(nèi)及內(nèi)置API性能詳解

    這篇文章主要為大家介紹了Canvas如何判斷點在形狀內(nèi)及內(nèi)置API性能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • TypeScript實用技巧?Nominal?Typing名義類型詳解

    TypeScript實用技巧?Nominal?Typing名義類型詳解

    這篇文章主要為大家介紹了TypeScript實用技巧?Nominal?Typing名義類型詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • JavaScript文檔對象模型DOM

    JavaScript文檔對象模型DOM

    這篇文章主要介紹了JavaScript文檔對象模型DOM,當(dāng)網(wǎng)頁被加載時,瀏覽器會創(chuàng)建頁面的文檔對象模型,通過可編程的對象模型,JavaScript 獲得了足夠的能力來創(chuàng)建動態(tài)的 HTML。下面來看看文章得詳細內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • 微信小程序通過api接口將json數(shù)據(jù)展現(xiàn)到小程序示例

    微信小程序通過api接口將json數(shù)據(jù)展現(xiàn)到小程序示例

    這篇文章主要介紹了微信小程序通過api接口將json數(shù)據(jù)展現(xiàn)到小程序示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • 微信小程序 視圖容器組件的詳解及實例代碼

    微信小程序 視圖容器組件的詳解及實例代碼

    這篇文章主要介紹了微信小程序 視圖容器組件的詳解及實例代碼的相關(guān)資料,這里對基礎(chǔ)知識進行了詳細介紹并附有簡單實例代碼,需要的朋友可以參考下
    2017-01-01
  • 微信小程序(應(yīng)用號)簡單實例應(yīng)用及實例詳解

    微信小程序(應(yīng)用號)簡單實例應(yīng)用及實例詳解

    這篇文章主要介紹了微信小程序(應(yīng)用號)簡單實例應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2016-09-09

最新評論