Skip to content

Commit 50cbe39

Browse files
authored
fix: useSyncState logic (#52)
1 parent 77db279 commit 50cbe39

File tree

2 files changed

+49
-41
lines changed

2 files changed

+49
-41
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"dependencies": {
4949
"@babel/runtime": "^7.11.1",
5050
"classnames": "^2.2.1",
51-
"rc-util": "^5.39.3"
51+
"rc-util": "^5.43.0"
5252
},
5353
"devDependencies": {
5454
"@rc-component/father-plugin": "^1.0.1",

src/hooks/useStatus.ts

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useEvent } from 'rc-util';
22
import useState from 'rc-util/lib/hooks/useState';
3+
import useSyncState from 'rc-util/lib/hooks/useSyncState';
34
import * as React from 'react';
45
import { useEffect, useRef } from 'react';
56
import type { CSSMotionProps } from '../CSSMotion';
@@ -51,9 +52,11 @@ export default function useStatus(
5152
): [MotionStatus, StepStatus, React.CSSProperties, boolean] {
5253
// Used for outer render usage to avoid `visible: false & status: none` to render nothing
5354
const [asyncVisible, setAsyncVisible] = useState<boolean>();
54-
const [status, setStatus] = useState<MotionStatus>(STATUS_NONE);
55+
const [getStatus, setStatus] = useSyncState<MotionStatus>(STATUS_NONE);
5556
const [style, setStyle] = useState<React.CSSProperties | undefined>(null);
5657

58+
const currentStatus = getStatus();
59+
5760
const mountedRef = useRef(false);
5861
const deadlineRef = useRef(null);
5962

@@ -69,11 +72,12 @@ export default function useStatus(
6972
* Clean up status & style
7073
*/
7174
function updateMotionEndStatus() {
72-
setStatus(STATUS_NONE, true);
75+
setStatus(STATUS_NONE);
7376
setStyle(null, true);
7477
}
7578

7679
const onInternalMotionEnd = useEvent((event: MotionEvent) => {
80+
const status = getStatus();
7781
// Do nothing since not in any transition status.
7882
// This may happen when `motionDeadline` trigger.
7983
if (status === STATUS_NONE) {
@@ -140,44 +144,48 @@ export default function useStatus(
140144
[STEP_PREPARE]?: MotionPrepareEventHandler;
141145
[STEP_START]?: MotionEventHandler;
142146
[STEP_ACTIVE]?: MotionEventHandler;
143-
}>(() => getEventHandlers(status), [status]);
144-
145-
const [startStep, step] = useStepQueue(status, !supportMotion, newStep => {
146-
// Only prepare step can be skip
147-
if (newStep === STEP_PREPARE) {
148-
const onPrepare = eventHandlers[STEP_PREPARE];
149-
if (!onPrepare) {
150-
return SkipStep;
147+
}>(() => getEventHandlers(currentStatus), [currentStatus]);
148+
149+
const [startStep, step] = useStepQueue(
150+
currentStatus,
151+
!supportMotion,
152+
newStep => {
153+
// Only prepare step can be skip
154+
if (newStep === STEP_PREPARE) {
155+
const onPrepare = eventHandlers[STEP_PREPARE];
156+
if (!onPrepare) {
157+
return SkipStep;
158+
}
159+
160+
return onPrepare(getDomElement());
151161
}
152162

153-
return onPrepare(getDomElement());
154-
}
155-
156-
// Rest step is sync update
157-
if (step in eventHandlers) {
158-
setStyle(eventHandlers[step]?.(getDomElement(), null) || null);
159-
}
163+
// Rest step is sync update
164+
if (step in eventHandlers) {
165+
setStyle(eventHandlers[step]?.(getDomElement(), null) || null);
166+
}
160167

161-
if (step === STEP_ACTIVE && status !== STATUS_NONE) {
162-
// Patch events when motion needed
163-
patchMotionEvents(getDomElement());
164-
165-
if (motionDeadline > 0) {
166-
clearTimeout(deadlineRef.current);
167-
deadlineRef.current = setTimeout(() => {
168-
onInternalMotionEnd({
169-
deadline: true,
170-
} as MotionEvent);
171-
}, motionDeadline);
168+
if (step === STEP_ACTIVE && currentStatus !== STATUS_NONE) {
169+
// Patch events when motion needed
170+
patchMotionEvents(getDomElement());
171+
172+
if (motionDeadline > 0) {
173+
clearTimeout(deadlineRef.current);
174+
deadlineRef.current = setTimeout(() => {
175+
onInternalMotionEnd({
176+
deadline: true,
177+
} as MotionEvent);
178+
}, motionDeadline);
179+
}
172180
}
173-
}
174181

175-
if (step === STEP_PREPARED) {
176-
updateMotionEndStatus();
177-
}
182+
if (step === STEP_PREPARED) {
183+
updateMotionEndStatus();
184+
}
178185

179-
return DoStep;
180-
});
186+
return DoStep;
187+
},
188+
);
181189

182190
const active = isActive(step);
183191
activeRef.current = active;
@@ -231,11 +239,11 @@ export default function useStatus(
231239
useEffect(() => {
232240
if (
233241
// Cancel appear
234-
(status === STATUS_APPEAR && !motionAppear) ||
242+
(currentStatus === STATUS_APPEAR && !motionAppear) ||
235243
// Cancel enter
236-
(status === STATUS_ENTER && !motionEnter) ||
244+
(currentStatus === STATUS_ENTER && !motionEnter) ||
237245
// Cancel leave
238-
(status === STATUS_LEAVE && !motionLeave)
246+
(currentStatus === STATUS_LEAVE && !motionLeave)
239247
) {
240248
setStatus(STATUS_NONE);
241249
}
@@ -257,14 +265,14 @@ export default function useStatus(
257265
firstMountChangeRef.current = true;
258266
}
259267

260-
if (asyncVisible !== undefined && status === STATUS_NONE) {
268+
if (asyncVisible !== undefined && currentStatus === STATUS_NONE) {
261269
// Skip first render is invisible since it's nothing changed
262270
if (firstMountChangeRef.current || asyncVisible) {
263271
onVisibleChanged?.(asyncVisible);
264272
}
265273
firstMountChangeRef.current = true;
266274
}
267-
}, [asyncVisible, status]);
275+
}, [asyncVisible, currentStatus]);
268276

269277
// ============================ Styles ============================
270278
let mergedStyle = style;
@@ -275,5 +283,5 @@ export default function useStatus(
275283
};
276284
}
277285

278-
return [status, step, mergedStyle, asyncVisible ?? visible];
286+
return [currentStatus, step, mergedStyle, asyncVisible ?? visible];
279287
}

0 commit comments

Comments
 (0)