diff --git a/components/_util/wave/WaveEffect.tsx b/components/_util/wave/WaveEffect.tsx index b64408e032..5171423718 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 4dcb7ce25a..088dcda925 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 b68058f2c8..9cd40a2cb8 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 3f28725c37..b25f888a5c 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 256fb10dce..24eaae85a7 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 (