Skip to content

Commit b9a0822

Browse files
committed
fix: compose existing child refs in CSSMotion
1 parent 3ea1a5d commit b9a0822

2 files changed

Lines changed: 52 additions & 9 deletions

File tree

src/CSSMotion.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable react/default-props-match-prop-types, react/no-multi-comp, react/prop-types */
22
import { getDOM } from '@rc-component/util/lib/Dom/findDOMNode';
3-
import { getNodeRef, supportRef } from '@rc-component/util/lib/ref';
3+
import { composeRef, getNodeRef, supportRef } from '@rc-component/util/lib/ref';
44
import { clsx } from 'clsx';
55
import * as React from 'react';
66
import { useRef } from 'react';
@@ -253,14 +253,12 @@ export function genCSSMotion(config: CSSMotionConfig) {
253253
) {
254254
const originNodeRef = getNodeRef(motionChildren);
255255

256-
if (!originNodeRef) {
257-
motionChildren = React.cloneElement(
258-
motionChildren as React.ReactElement,
259-
{
260-
ref: nodeRef,
261-
},
262-
);
263-
}
256+
motionChildren = React.cloneElement(
257+
motionChildren as React.ReactElement,
258+
{
259+
ref: originNodeRef ? composeRef(originNodeRef, nodeRef) : nodeRef,
260+
},
261+
);
264262
}
265263

266264
return motionChildren;

tests/CSSMotion.spec.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,51 @@ describe('CSSMotion', () => {
942942

943943
expect(ReactDOM.findDOMNode).not.toHaveBeenCalled();
944944
});
945+
946+
it('supports existing child refs for motion end', () => {
947+
const motionRef = React.createRef<CSSMotionRef>();
948+
const childRef = React.createRef<HTMLDivElement>();
949+
950+
const Demo = ({ visible }: { visible: boolean }) => (
951+
<CSSMotion
952+
motionName="transition"
953+
motionAppear={false}
954+
visible={visible}
955+
ref={motionRef}
956+
>
957+
{({ style, className }) => (
958+
<div
959+
ref={childRef}
960+
style={style}
961+
className={clsx('motion-box', className)}
962+
/>
963+
)}
964+
</CSSMotion>
965+
);
966+
967+
const { container, rerender } = render(<Demo visible />);
968+
969+
act(() => {
970+
jest.runAllTimers();
971+
});
972+
973+
expect(motionRef.current.nativeElement).toBe(childRef.current);
974+
975+
rerender(<Demo visible={false} />);
976+
977+
act(() => {
978+
jest.runAllTimers();
979+
});
980+
981+
fireEvent.transitionEnd(childRef.current!);
982+
983+
act(() => {
984+
jest.runAllTimers();
985+
});
986+
987+
expect(container.querySelector('.motion-box')).toBeFalsy();
988+
expect(ReactDOM.findDOMNode).not.toHaveBeenCalled();
989+
});
945990
});
946991

947992
describe('onVisibleChanged', () => {

0 commit comments

Comments
 (0)