From 91878f82ad570dfd88a959e4c11a3f559916e9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E7=88=B1=E5=90=83=E7=99=BD=E8=90=9D?= =?UTF-8?q?=E5=8D=9C?= Date: Tue, 10 Dec 2024 10:58:00 +0800 Subject: [PATCH 1/2] refactor: update ref logic (#51952) * refactor: update ref logic * chore: clean up * chore: coverage adjust * test: coverage * chore: back of code --- components/_util/wave/WaveEffect.tsx | 7 +++++++ components/_util/wave/index.ts | 4 ++-- components/form/__tests__/ref.test.tsx | 19 ++++++++++++++++++- components/form/hooks/useItemRef.ts | 6 ++++-- components/menu/OverrideContext.tsx | 4 ++-- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/components/_util/wave/WaveEffect.tsx b/components/_util/wave/WaveEffect.tsx index b64408e03268..517142371876 100644 --- a/components/_util/wave/WaveEffect.tsx +++ b/components/_util/wave/WaveEffect.tsx @@ -140,6 +140,13 @@ const WaveEffect: React.FC = (props) => { const showWaveEffect: ShowWaveEffect = (target, info) => { const { component } = info; + // Skip if not support `render` since `rc-util` render not support React 19 + // TODO: remove this check in v6 + /* istanbul ignore next */ + if (!render) { + return; + } + // Skip for unchecked checkbox if (component === 'Checkbox' && !target.querySelector('input')?.checked) { return; diff --git a/components/_util/wave/index.ts b/components/_util/wave/index.ts index 4dcb7ce25a36..088dcda925f1 100644 --- a/components/_util/wave/index.ts +++ b/components/_util/wave/index.ts @@ -1,7 +1,7 @@ import React, { useContext, useRef } from 'react'; import classNames from 'classnames'; import isVisible from 'rc-util/lib/Dom/isVisible'; -import { composeRef, supportRef } from 'rc-util/lib/ref'; +import { composeRef, getNodeRef, supportRef } from 'rc-util/lib/ref'; import type { ConfigConsumerProps } from '../../config-provider'; import { ConfigContext } from '../../config-provider'; @@ -64,7 +64,7 @@ const Wave: React.FC = (props) => { return children ?? null; } - const ref = supportRef(children) ? composeRef((children as any).ref, containerRef) : containerRef; + const ref = supportRef(children) ? composeRef(getNodeRef(children), containerRef) : containerRef; return cloneElement(children, { ref }); }; diff --git a/components/form/__tests__/ref.test.tsx b/components/form/__tests__/ref.test.tsx index b68058f2c821..9cd40a2cb826 100644 --- a/components/form/__tests__/ref.test.tsx +++ b/components/form/__tests__/ref.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import type { FormRef } from 'rc-field-form/lib/interface'; -import Form from '..'; +import Form, { FormInstance } from '..'; import { fireEvent, render } from '../../../tests/utils'; import Button from '../../button'; import type { InputRef } from '../../input'; @@ -94,4 +94,21 @@ describe('Form.Ref', () => { expect(container.querySelector('.ant-form')).toBe(formRef.current?.nativeElement); }); + + // TODO: this is no need to test in React 19 + it('not crash if not support Ref', () => { + const NoRefComp = () =>
; + + const formRef = React.createRef(); + render( +
+ + + +
, + ); + + const ele = formRef.current?.getFieldInstance('bamboo'); + expect(ele).toBeFalsy(); + }); }); diff --git a/components/form/hooks/useItemRef.ts b/components/form/hooks/useItemRef.ts index 3f28725c371a..b25f888a5ce1 100644 --- a/components/form/hooks/useItemRef.ts +++ b/components/form/hooks/useItemRef.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { composeRef } from 'rc-util/lib/ref'; +import { composeRef, getNodeRef } from 'rc-util/lib/ref'; import { FormContext } from '../context'; import type { InternalNamePath } from '../interface'; @@ -13,8 +13,10 @@ export default function useItemRef() { }>({}); function getRef(name: InternalNamePath, children: any) { + // Outer caller already check the `supportRef` const childrenRef: React.Ref = - children && typeof children === 'object' && children.ref; + children && typeof children === 'object' && getNodeRef(children); + const nameStr = name.join('_'); if (cacheRef.current.name !== nameStr || cacheRef.current.originRef !== childrenRef) { cacheRef.current.name = nameStr; diff --git a/components/menu/OverrideContext.tsx b/components/menu/OverrideContext.tsx index 256fb10dced9..24eaae85a73f 100644 --- a/components/menu/OverrideContext.tsx +++ b/components/menu/OverrideContext.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { supportNodeRef, useComposeRef } from 'rc-util/lib/ref'; +import { getNodeRef, supportNodeRef, useComposeRef } from 'rc-util/lib/ref'; import ContextIsolator from '../_util/ContextIsolator'; import type { MenuProps } from './menu'; @@ -39,7 +39,7 @@ export const OverrideProvider = React.forwardRef< ); const canRef = supportNodeRef(children); - const mergedRef = useComposeRef(ref, canRef ? children.ref : null); + const mergedRef = useComposeRef(ref, canRef ? getNodeRef(children) : null); return ( From 9b4400b2683a2c6175a744f59866083209b0bb6c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Dec 2024 14:07:20 +0800 Subject: [PATCH 2/2] chore: upgrade deps (#51959) Co-authored-by: afc163 <507615+afc163@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 95dd183c5ebf..a60cdfff5782 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "@rc-component/mutate-observer": "^1.1.0", "@rc-component/qrcode": "~1.0.0", "@rc-component/tour": "~1.15.1", - "@rc-component/trigger": "^2.2.5", + "@rc-component/trigger": "^2.2.6", "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.11",