Skip to content

Commit 6daef4e

Browse files
authored
Make xViewTransitionToHostInstances helpers reusable (#32611)
This prepares from being able to reuse some this in ApplyGesture. These all start with resetting a counter but it's tricky to have to remember to do this and tricky to do from the outside of this module. So we make an exported helper that does the resetting. Ideally it gets inlined. We also stop passing "current" to measureViewTransitionHostInstances. Same thing for cancelViewTransitionHostInstances. This doesn't make sense for "nested" which has not updated and so might not have an alternate. Instead we pass in the old and new name if they might be different.
1 parent 3e95680 commit 6daef4e

File tree

2 files changed

+110
-67
lines changed

2 files changed

+110
-67
lines changed

packages/react-reconciler/src/ReactFiberCommitViewTransitions.js

Lines changed: 103 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,40 @@ export let viewTransitionCancelableChildren: null | Array<
7171
Instance | string | Props,
7272
> = null; // tupled array where each entry is [instance: Instance, oldName: string, props: Props]
7373

74-
export function setViewTransitionCancelableChildren(
75-
children: null | Array<Instance | string | Props>,
74+
export function pushViewTransitionCancelableScope(): null | Array<
75+
Instance | string | Props,
76+
> {
77+
const prevChildren = viewTransitionCancelableChildren;
78+
viewTransitionCancelableChildren = null;
79+
return prevChildren;
80+
}
81+
82+
export function popViewTransitionCancelableScope(
83+
prevChildren: null | Array<Instance | string | Props>,
7684
): void {
77-
viewTransitionCancelableChildren = children;
85+
viewTransitionCancelableChildren = prevChildren;
7886
}
7987

8088
let viewTransitionHostInstanceIdx = 0;
8189

82-
function applyViewTransitionToHostInstances(
90+
export function applyViewTransitionToHostInstances(
91+
child: null | Fiber,
92+
name: string,
93+
className: ?string,
94+
collectMeasurements: null | Array<InstanceMeasurement>,
95+
stopAtNestedViewTransitions: boolean,
96+
): boolean {
97+
viewTransitionHostInstanceIdx = 0;
98+
return applyViewTransitionToHostInstancesRecursive(
99+
child,
100+
name,
101+
className,
102+
collectMeasurements,
103+
stopAtNestedViewTransitions,
104+
);
105+
}
106+
107+
function applyViewTransitionToHostInstancesRecursive(
83108
child: null | Fiber,
84109
name: string,
85110
className: ?string,
@@ -128,7 +153,7 @@ function applyViewTransitionToHostInstances(
128153
// inner most one is the one that handles the update.
129154
} else {
130155
if (
131-
applyViewTransitionToHostInstances(
156+
applyViewTransitionToHostInstancesRecursive(
132157
child.child,
133158
name,
134159
className,
@@ -207,7 +232,6 @@ function commitAppearingPairViewTransitions(placement: Fiber): void {
207232
if (className !== 'none') {
208233
// We found a new appearing view transition with the same name as this deletion.
209234
// We'll transition between them.
210-
viewTransitionHostInstanceIdx = 0;
211235
const inViewport = applyViewTransitionToHostInstances(
212236
child.child,
213237
name,
@@ -242,7 +266,6 @@ export function commitEnterViewTransitions(placement: Fiber): void {
242266
state.paired ? props.share : props.enter,
243267
);
244268
if (className !== 'none') {
245-
viewTransitionHostInstanceIdx = 0;
246269
const inViewport = applyViewTransitionToHostInstances(
247270
placement.child,
248271
name,
@@ -310,7 +333,6 @@ function commitDeletedPairViewTransitions(deletion: Fiber): void {
310333
);
311334
if (className !== 'none') {
312335
// We found a new appearing view transition with the same name as this deletion.
313-
viewTransitionHostInstanceIdx = 0;
314336
const inViewport = applyViewTransitionToHostInstances(
315337
child.child,
316338
name,
@@ -361,7 +383,6 @@ export function commitExitViewTransitions(deletion: Fiber): void {
361383
pair !== undefined ? props.share : props.exit,
362384
);
363385
if (className !== 'none') {
364-
viewTransitionHostInstanceIdx = 0;
365386
const inViewport = applyViewTransitionToHostInstances(
366387
deletion.child,
367388
name,
@@ -449,7 +470,6 @@ export function commitBeforeUpdateViewTransition(
449470
return;
450471
}
451472
}
452-
viewTransitionHostInstanceIdx = 0;
453473
applyViewTransitionToHostInstances(
454474
current.child,
455475
oldName,
@@ -472,7 +492,6 @@ export function commitNestedViewTransitions(changedParent: Fiber): void {
472492
props.layout,
473493
);
474494
if (className !== 'none') {
475-
viewTransitionHostInstanceIdx = 0;
476495
applyViewTransitionToHostInstances(
477496
child.child,
478497
name,
@@ -553,9 +572,22 @@ export function restoreNestedViewTransitions(changedParent: Fiber): void {
553572
}
554573
}
555574

556-
function cancelViewTransitionHostInstances(
557-
currentViewTransition: Fiber,
575+
export function cancelViewTransitionHostInstances(
558576
child: null | Fiber,
577+
oldName: string,
578+
stopAtNestedViewTransitions: boolean,
579+
): void {
580+
viewTransitionHostInstanceIdx = 0;
581+
cancelViewTransitionHostInstancesRecursive(
582+
child,
583+
oldName,
584+
stopAtNestedViewTransitions,
585+
);
586+
}
587+
588+
function cancelViewTransitionHostInstancesRecursive(
589+
child: null | Fiber,
590+
oldName: string,
559591
stopAtNestedViewTransitions: boolean,
560592
): void {
561593
if (!supportsMutation) {
@@ -564,10 +596,6 @@ function cancelViewTransitionHostInstances(
564596
while (child !== null) {
565597
if (child.tag === HostComponent) {
566598
const instance: Instance = child.stateNode;
567-
const oldName = getViewTransitionName(
568-
currentViewTransition.memoizedProps,
569-
currentViewTransition.stateNode,
570-
);
571599
if (viewTransitionCancelableChildren === null) {
572600
viewTransitionCancelableChildren = [];
573601
}
@@ -589,21 +617,42 @@ function cancelViewTransitionHostInstances(
589617
// Skip any nested view transitions for updates since in that case the
590618
// inner most one is the one that handles the update.
591619
} else {
592-
cancelViewTransitionHostInstances(
593-
currentViewTransition,
620+
cancelViewTransitionHostInstancesRecursive(
594621
child.child,
622+
oldName,
595623
stopAtNestedViewTransitions,
596624
);
597625
}
598626
child = child.sibling;
599627
}
600628
}
601629

602-
function measureViewTransitionHostInstances(
603-
currentViewTransition: Fiber,
630+
export function measureViewTransitionHostInstances(
604631
parentViewTransition: Fiber,
605632
child: null | Fiber,
606-
name: string,
633+
newName: string,
634+
oldName: string,
635+
className: ?string,
636+
previousMeasurements: null | Array<InstanceMeasurement>,
637+
stopAtNestedViewTransitions: boolean,
638+
): boolean {
639+
viewTransitionHostInstanceIdx = 0;
640+
return measureViewTransitionHostInstancesRecursive(
641+
parentViewTransition,
642+
child,
643+
newName,
644+
oldName,
645+
className,
646+
previousMeasurements,
647+
stopAtNestedViewTransitions,
648+
);
649+
}
650+
651+
function measureViewTransitionHostInstancesRecursive(
652+
parentViewTransition: Fiber,
653+
child: null | Fiber,
654+
newName: string,
655+
oldName: string,
607656
className: ?string,
608657
previousMeasurements: null | Array<InstanceMeasurement>,
609658
stopAtNestedViewTransitions: boolean,
@@ -654,10 +703,10 @@ function measureViewTransitionHostInstances(
654703
applyViewTransitionName(
655704
instance,
656705
viewTransitionHostInstanceIdx === 0
657-
? name
706+
? newName
658707
: // If we have multiple Host Instances below, we add a suffix to the name to give
659708
// each one a unique name.
660-
name + '_' + viewTransitionHostInstanceIdx,
709+
newName + '_' + viewTransitionHostInstanceIdx,
661710
className,
662711
);
663712
}
@@ -667,10 +716,6 @@ function measureViewTransitionHostInstances(
667716
// animating it. However, in the current model this only works if the parent also
668717
// doesn't animate. So we have to queue these and wait until we complete the parent
669718
// to cancel them.
670-
const oldName = getViewTransitionName(
671-
currentViewTransition.memoizedProps,
672-
currentViewTransition.stateNode,
673-
);
674719
if (viewTransitionCancelableChildren === null) {
675720
viewTransitionCancelableChildren = [];
676721
}
@@ -696,11 +741,11 @@ function measureViewTransitionHostInstances(
696741
parentViewTransition.flags |= child.flags & AffectedParentLayout;
697742
} else {
698743
if (
699-
measureViewTransitionHostInstances(
700-
currentViewTransition,
744+
measureViewTransitionHostInstancesRecursive(
701745
parentViewTransition,
702746
child.child,
703-
name,
747+
newName,
748+
oldName,
704749
className,
705750
previousMeasurements,
706751
stopAtNestedViewTransitions,
@@ -719,6 +764,11 @@ export function measureUpdateViewTransition(
719764
finishedWork: Fiber,
720765
): boolean {
721766
const props: ViewTransitionProps = finishedWork.memoizedProps;
767+
const newName = getViewTransitionName(props, finishedWork.stateNode);
768+
const oldName = getViewTransitionName(
769+
current.memoizedProps,
770+
current.stateNode,
771+
);
722772
const updateClassName: ?string = getViewTransitionClassName(
723773
props.className,
724774
props.update,
@@ -745,24 +795,21 @@ export function measureUpdateViewTransition(
745795
if (layoutClassName === 'none') {
746796
// If we did not update, then all changes are considered a layout. We'll
747797
// attempt to cancel.
748-
viewTransitionHostInstanceIdx = 0;
749-
cancelViewTransitionHostInstances(current, finishedWork.child, true);
798+
cancelViewTransitionHostInstances(finishedWork.child, oldName, true);
750799
return false;
751800
}
752801
// We didn't update but we might still apply layout so we measure each
753802
// instance to see if it moved or resized.
754803
className = layoutClassName;
755804
}
756-
const name = getViewTransitionName(props, finishedWork.stateNode);
757805
// If nothing changed due to a mutation, or children changing size
758806
// and the measurements end up unchanged, we should restore it to not animate.
759-
viewTransitionHostInstanceIdx = 0;
760807
const previousMeasurements = current.memoizedState;
761808
const inViewport = measureViewTransitionHostInstances(
762-
current,
763809
finishedWork,
764810
finishedWork.child,
765-
name,
811+
newName,
812+
oldName,
766813
className,
767814
previousMeasurements,
768815
true,
@@ -782,29 +829,25 @@ export function measureNestedViewTransitions(changedParent: Fiber): void {
782829
let child = changedParent.child;
783830
while (child !== null) {
784831
if (child.tag === ViewTransitionComponent) {
785-
const current = child.alternate;
786-
if (current !== null) {
787-
const props: ViewTransitionProps = child.memoizedProps;
788-
const name = getViewTransitionName(props, child.stateNode);
789-
const className: ?string = getViewTransitionClassName(
790-
props.className,
791-
props.layout,
792-
);
793-
viewTransitionHostInstanceIdx = 0;
794-
const inViewport = measureViewTransitionHostInstances(
795-
current,
796-
child,
797-
child.child,
798-
name,
799-
className,
800-
child.memoizedState,
801-
false,
802-
);
803-
if ((child.flags & Update) === NoFlags || !inViewport) {
804-
// Nothing changed.
805-
} else {
806-
scheduleViewTransitionEvent(child, props.onLayout);
807-
}
832+
const props: ViewTransitionProps = child.memoizedProps;
833+
const name = getViewTransitionName(props, child.stateNode);
834+
const className: ?string = getViewTransitionClassName(
835+
props.className,
836+
props.layout,
837+
);
838+
const inViewport = measureViewTransitionHostInstances(
839+
child,
840+
child.child,
841+
name,
842+
name, // Since this is unchanged, new and old name is the same.
843+
className,
844+
child.memoizedState,
845+
false,
846+
);
847+
if ((child.flags & Update) === NoFlags || !inViewport) {
848+
// Nothing changed.
849+
} else {
850+
scheduleViewTransitionEvent(child, props.onLayout);
808851
}
809852
} else if ((child.subtreeFlags & ViewTransitionStatic) !== NoFlags) {
810853
measureNestedViewTransitions(child);

packages/react-reconciler/src/ReactFiberCommitWork.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ import {
254254
resetAppearingViewTransitions,
255255
trackAppearingViewTransition,
256256
viewTransitionCancelableChildren,
257-
setViewTransitionCancelableChildren,
257+
pushViewTransitionCancelableScope,
258+
popViewTransitionCancelableScope,
258259
} from './ReactFiberCommitViewTransitions';
259260
import {
260261
viewTransitionMutationContext,
@@ -2474,14 +2475,14 @@ function commitAfterMutationEffectsOnFiber(
24742475
switch (finishedWork.tag) {
24752476
case HostRoot: {
24762477
viewTransitionContextChanged = false;
2477-
setViewTransitionCancelableChildren(null);
2478+
pushViewTransitionCancelableScope();
24782479
recursivelyTraverseAfterMutationEffects(root, finishedWork, lanes);
24792480
if (!viewTransitionContextChanged) {
24802481
// If we didn't leak any resizing out to the root, we don't have to transition
24812482
// the root itself. This means that we can now safely cancel any cancellations
24822483
// that bubbled all the way up.
24832484
const cancelableChildren = viewTransitionCancelableChildren;
2484-
setViewTransitionCancelableChildren(null);
2485+
popViewTransitionCancelableScope(null);
24852486
if (cancelableChildren !== null) {
24862487
for (let i = 0; i < cancelableChildren.length; i += 3) {
24872488
cancelViewTransitionName(
@@ -2532,9 +2533,8 @@ function commitAfterMutationEffectsOnFiber(
25322533
const wasMutated = (finishedWork.flags & Update) !== NoFlags;
25332534

25342535
const prevContextChanged = viewTransitionContextChanged;
2535-
const prevCancelableChildren = viewTransitionCancelableChildren;
2536+
const prevCancelableChildren = pushViewTransitionCancelableScope();
25362537
viewTransitionContextChanged = false;
2537-
setViewTransitionCancelableChildren(null);
25382538
recursivelyTraverseAfterMutationEffects(root, finishedWork, lanes);
25392539

25402540
if (viewTransitionContextChanged) {
@@ -2557,7 +2557,7 @@ function commitAfterMutationEffectsOnFiber(
25572557
prevCancelableChildren,
25582558
viewTransitionCancelableChildren,
25592559
);
2560-
setViewTransitionCancelableChildren(prevCancelableChildren);
2560+
popViewTransitionCancelableScope(prevCancelableChildren);
25612561
}
25622562
// TODO: If this doesn't end up canceled, because a parent animates,
25632563
// then we should probably issue an event since this instance is part of it.
@@ -2571,7 +2571,7 @@ function commitAfterMutationEffectsOnFiber(
25712571
);
25722572

25732573
// If this boundary did update, we cannot cancel its children so those are dropped.
2574-
setViewTransitionCancelableChildren(prevCancelableChildren);
2574+
popViewTransitionCancelableScope(prevCancelableChildren);
25752575
}
25762576

25772577
if ((finishedWork.flags & AffectedParentLayout) !== NoFlags) {

0 commit comments

Comments
 (0)