Skip to content

Revisit timing to capture old/new nodes (#56877)#56877

Closed
zeyap wants to merge 1 commit into
facebook:mainfrom
zeyap:export-D105214322
Closed

Revisit timing to capture old/new nodes (#56877)#56877
zeyap wants to merge 1 commit into
facebook:mainfrom
zeyap:export-D105214322

Conversation

@zeyap
Copy link
Copy Markdown
Contributor

@zeyap zeyap commented May 18, 2026

Summary:

Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when applyViewTransitionName is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because applyViewTransitionName(old) for next transition can be called when the previous transition is still ongoing. In fact applyViewTransitionName(old) is guaranteed to be called before mutationCallback in a transition while applyViewTransitionName(new) is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 18, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 18, 2026

@zeyap has exported this pull request. If you are a Meta employee, you can view the originating Diff in D105214322.

@meta-codesync meta-codesync Bot changed the title Revisit timing to capture old/new nodes Revisit timing to capture old/new nodes (#56877) May 28, 2026
zeyap added a commit to zeyap/react-native that referenced this pull request May 28, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Differential Revision: D105214322
@zeyap zeyap force-pushed the export-D105214322 branch from 5640a06 to 7b03379 Compare May 28, 2026 20:59
zeyap added a commit to zeyap/react-native that referenced this pull request May 28, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
@zeyap zeyap force-pushed the export-D105214322 branch from 7b03379 to c599d47 Compare May 28, 2026 21:21
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
@zeyap zeyap force-pushed the export-D105214322 branch from c599d47 to addbca4 Compare May 29, 2026 13:11
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
zeyap added a commit to zeyap/react-native that referenced this pull request May 29, 2026
Summary:

## Changelog:

[Internal] [Changed] - Revisit timing to capture old/new nodes

Previously, when `applyViewTransitionName` is called from react reconciler, if there is active viewtransition, we decide it's applying to new node. This was incorrect because `applyViewTransitionName(old)` for next transition can be called when the previous transition is still ongoing. In fact `applyViewTransitionName(old)` is guaranteed to be called before mutationCallback in a transition while `applyViewTransitionName(new)` is inside mutationCallback. So that is a better criteria to separate old and new cases. Given mutationCallback is synchronous on JS thread we can just use a boolean flag to tell the timing.

Given this interleaved situation, when we clean up resources (for new/old nodes) of a transition at its end, we should also avoid removing those for a pending transition. Introducing transitionId for this case.

Reviewed By: Abbondanzo

Differential Revision: D105214322
@meta-codesync meta-codesync Bot closed this in ee43ce7 May 29, 2026
@facebook-github-tools facebook-github-tools Bot added the Merged This PR has been merged. label May 29, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync Bot commented May 29, 2026

This pull request has been merged in ee43ce7.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @zeyap in ee43ce7

When will my fix make it into a release? | How to file a pick request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants