My PRs to ant-design: PR1
Published: 2023-10-17 06:40:47

[Ant Design](https://ant.design/) is a popular design system and a set of React UI components created by Ant Financial, the financial subsidiary of Alibaba Group. It provides a collection of high-quality and customizable components and design patterns for building modern and responsive web applications. Ant Design is widely used in web development, especially for creating user interfaces with a consistent and visually appealing design. It includes components for layout, navigation, forms, data display, and more, making it a valuable resource for developers looking to create user-friendly and aesthetically pleasing web applications. I am very happy that I was able to provide two pull requests for [ant-design](https://github.com/ant-design/ant-design) in this October. In fact, about a year ago or much earlier, I had tried to fork this project, but at that time, I didn't even know what unit tests were. Now, I have finally achieved one of my goals, and I would like to document the process of my pull requests.

This blog post will document the first [PR](https://github.com/ant-design/ant-design/pull/45164) process. I will introduce the second PR process in the following blog post.

## Issue 
The [issue](https://github.com/ant-design/ant-design/issues/45070) was opened by [sefaphlvn](https://github.com/sefaphlvn). This issue was about the component [CheckableTag](https://ant.design/components/tag#tag-demo-checkable). It belongs to Tag but works like Checkbox, and user can click it to toggle checked state.
![CheckableTag](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i15t66y6soxv8eudasmw.png) 
 
The problem was when using CheckableTag wrapped by [Popover](https://ant.design/components/popover) component and in Strict Mode, the [codes](https://codesandbox.io/s/antd-reproduction-template-forked-nkylm6?file=/index.js) will trigger the findDOMNode method of React, which now is deprecated in StrictMode, and sending warnings:
![issuelog](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qo5z7g9bu0q19smkxhpi.png)

## Debug process
The console log shows about the problem by the CheckableTag:

```
CheckableTag@https://pwfnyd.csb.app/node_modules/antd/es/tag/CheckableTag.js:22:135
```

Additionally, the main member of ant-design [MadCcc](https://github.com/MadCcc) also expressed the same viewpoint: 

![viewpoint](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71ggcqaobfmiad63m1o6.png)

That's really helpful for me to debug and validate changes. To quickly reproduce, I use the relevant code's logic to replace the project's demo code. Here is my codes (`components/tag/demo/checkable.tsx`):

```tsx
import React, { StrictMode, useState } from 'react';
import { Anchor, Popover, Space, Tag, version } from 'antd';

const { CheckableTag } = Tag;

const App: React.FC = () => {
  const tags = ['tag1', 'tag2', 'tag3', 'tag4', 'tag5'];

  return (
    <StrictMode>
      <span style={{ marginRight: 8 }}>Categories:</span>
      <Space size={[0, 8]} wrap>
        <Anchor
          affix={false}
          style={{ display: 'block', marginRight: 10 }}
          direction="vertical"
          items={tags.map((tag, index) => ({
            key: index.toString(),
            title: (
              <div style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
                <span
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    flex: '1 1 auto',
                    maxWidth: '100%',
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                  }}
                  onClick={(e) => {
                    e.stopPropagation();
                    e.preventDefault();
                  }}
                >
                  <Popover
                    content="This field is unchangeable."
                    title={<div className="warning-popover-title">Info</div>}
                  >
                    <CheckableTag
                      key={tag}
                      className="ellipsis-tag"
                      checked={true}
                      onChange={(checked) => console.log('test')}
                    >
                      <span>{tag}</span>
                    </CheckableTag>
                  </Popover>
                </span>
              </div>
            ),
          }))}
        ></Anchor>
      </Space>
    </StrictMode>
  );
};

export default App;

```

As expected, when running in local development environment the same error shows:
![demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n25r0dvt5ows8tjtftql.png)

I then found the code of CheckableTag which is `components/tag/CheckableTag.tsx` need to update to support ref. Here I use `React.forwardRef` to fix.

Before:

```tsx
const CheckableTag: React.FC<CheckableTagProps> = (props) => {
  const {
    prefixCls: customizePrefixCls,
    style,
    className,
    checked,
    onChange,
    onClick,
    ...restProps
  } = props;

  //...

  return wrapSSR(
    <span
      {...restProps}
      style={{
        ...style,
        ...tag?.style,
      }}
      className={cls}
      onClick={handleClick}
    />,
  );
};
```

After:

```tsx
const CheckableTag = React.forwardRef<HTMLSpanElement, CheckableTagProps>((props, ref) => {
  const {
    prefixCls: customizePrefixCls,
    style,
    className,
    checked,
    onChange,
    onClick,
    ...restProps
  } = props;
  
  //...

  return wrapSSR(
    <span
      {...restProps}
      ref={ref}
      style={{
        ...style,
        ...tag?.style,
      }}
      className={cls}
      onClick={handleClick}
    />,
  );
});

```
More details see the [commit](https://github.com/ant-design/ant-design/pull/45164/files)

Then I could check again locally and no errors showed as expected.

## Reflection

The key to fixing this issue is that I already knew about `React.forwardRef`, but now I've forgotten when and how I learned about it. So the insight I've gained is that past learning will eventually come in handy. When I was working on resolving this problem, I also referenced the answers provided by ChatGPT. You can try give ChatGPT the code and ask it how to support refs. I found that ChatGPT would also use `React.forwardRef`. If you're not familiar with `React.forwardRef`, it's also a good learning opportunity. If you have any questions or thoughts, feel free to leave a comment. Until we meet again, stay curious and stay inspired!