From 268bd6e2d6ae93f6d80d703996f08b97cd5df09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E5=BB=B7=E5=AE=89?= <73953029+nrps9909@users.noreply.github.com> Date: Fri, 28 Aug 2026 15:02:36 +0800 Subject: [PATCH] fix: use latest motion step handlers --- src/hooks/useStatus.ts | 10 +++++----- tests/CSSMotion.spec.tsx | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/hooks/useStatus.ts b/src/hooks/useStatus.ts index aad729d..923401a 100644 --- a/src/hooks/useStatus.ts +++ b/src/hooks/useStatus.ts @@ -146,11 +146,11 @@ export default function useStatus( } }; - const eventHandlers = React.useMemo<{ + const eventHandlers: { [STEP_PREPARE]?: MotionPrepareEventHandler; [STEP_START]?: MotionEventHandler; [STEP_ACTIVE]?: MotionEventHandler; - }>(() => getEventHandlers(currentStatus), [currentStatus]); + } = getEventHandlers(currentStatus); const [startStep, step] = useStepQueue( currentStatus, @@ -318,8 +318,8 @@ export default function useStatus( motionAppear ? 'NONE' : // Enter or Leave check - step === STEP_START || step === STEP_ACTIVE - ? styleStep === step - : true, + step === STEP_START || step === STEP_ACTIVE + ? styleStep === step + : true, ]; } diff --git a/tests/CSSMotion.spec.tsx b/tests/CSSMotion.spec.tsx index 8f4a946..2fd34fd 100644 --- a/tests/CSSMotion.spec.tsx +++ b/tests/CSSMotion.spec.tsx @@ -161,6 +161,45 @@ describe('CSSMotion', () => { }, ); + it('uses the latest active handler during a motion', () => { + const firstActive = jest.fn(() => ({ opacity: 0.1 })); + const latestActive = jest.fn(() => ({ opacity: 0.9 })); + const Demo = ({ + visible, + onEnterActive, + }: { + visible: boolean; + onEnterActive: CSSMotionProps['onEnterActive']; + }) => ( + + {({ style, className }) => ( +
+ )} + + ); + + const { container, rerender } = render( + , + ); + rerender(); + rerender(); + + act(() => { + jest.runAllTimers(); + }); + + expect(firstActive).not.toHaveBeenCalled(); + expect(latestActive).toHaveBeenCalledTimes(1); + expect(container.querySelector('.motion-box')).toHaveStyle({ + opacity: '0.9', + }); + }); + it('leaveClassName should add to dom', () => { const genMotion = props => { const { visible, leavedClassName } = props;