Skip to content

Commit 5b054f5

Browse files
authored
fix: Animated styles not registered after unfreeze (#8325)
## Summary This PR fixes animated styles registering on freeze/unfreeze. The issue was caused by the cleanup made in the `componentWillUnmount`, which removes the current view tag from the animated style's view descriptors. This view tag was never added later on because only the style object references were compared and, because the style prop didn't change between freeze/unfreeze, we assumed that there is no need to register the animated styles again. This assumption was correct as long as the `componentWillUnmount` was executed before the component was actually unmounted (but, it turns out that this method is also called when the component is frozen, not unmounted). ## Example recordings The pink rectangle with the animated style attached didn't animate after navigating back to the previously frozen screen. | Before | After | |-|-| | <video src="https://github.com/user-attachments/assets/eaaa21ae-266a-4649-8fb3-b492e80fc186" /> | <video src="https://github.com/user-attachments/assets/744eb171-d231-49aa-92f2-e89174dd2b15" /> |
1 parent 474c147 commit 5b054f5

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

packages/react-native-reanimated/src/ViewDescriptorsSet.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ export interface ViewDescriptorsSet {
77
shareableViewDescriptors: SharedValue<Descriptor[]>;
88
add: (item: Descriptor, updaterContainer?: StyleUpdaterContainer) => void;
99
remove: (viewTag: number) => void;
10+
has: (viewTag: number) => boolean;
1011
}
1112

1213
export function makeViewDescriptorsSet(): ViewDescriptorsSet {
1314
const shareableViewDescriptors = makeMutable<Descriptor[]>([]);
15+
const viewTags = new Set<number>();
16+
1417
const data: ViewDescriptorsSet = {
1518
shareableViewDescriptors,
1619
add: (item: Descriptor, updaterContainer?: StyleUpdaterContainer) => {
20+
viewTags.add(item.tag as number);
1721
const updater = updaterContainer?.current;
1822
shareableViewDescriptors.modify((descriptors) => {
1923
'worklet';
@@ -31,6 +35,7 @@ export function makeViewDescriptorsSet(): ViewDescriptorsSet {
3135
},
3236

3337
remove: (viewTag: number) => {
38+
viewTags.delete(viewTag);
3439
shareableViewDescriptors.modify((descriptors) => {
3540
'worklet';
3641
const index = descriptors.findIndex(
@@ -42,6 +47,9 @@ export function makeViewDescriptorsSet(): ViewDescriptorsSet {
4247
return descriptors;
4348
}, false);
4449
},
50+
51+
has: (viewTag: number) => viewTags.has(viewTag),
4552
};
53+
4654
return data;
4755
}

packages/react-native-reanimated/src/createAnimatedComponent/AnimatedComponent.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ export default class AnimatedComponent
212212
const { viewTag, shadowNodeWrapper } = this._getViewInfo();
213213
const newStyles = new Set<StyleProps>(currentStyles);
214214

215+
const isStyleAttached = (style: StyleProps) =>
216+
style.viewDescriptors.has(viewTag);
217+
215218
// remove old styles
216219
if (prevStyles) {
217220
// in most of the cases, views have only a single animated style and it remains unchanged
@@ -220,14 +223,14 @@ export default class AnimatedComponent
220223
prevStyles.length === 1 &&
221224
currentStyles[0] === prevStyles[0];
222225

223-
if (hasOneSameStyle) {
226+
if (hasOneSameStyle && isStyleAttached(prevStyles[0])) {
224227
return;
225228
}
226229

227230
// otherwise, remove each style that is not present in new styles
228231
for (const prevStyle of prevStyles) {
229232
const isPresent = currentStyles.some((style) => {
230-
if (style === prevStyle) {
233+
if (style === prevStyle && isStyleAttached(style)) {
231234
newStyles.delete(style);
232235
return true;
233236
}
@@ -238,6 +241,7 @@ export default class AnimatedComponent
238241
}
239242
}
240243
}
244+
241245
newStyles.forEach((style) => {
242246
style.viewDescriptors.add(
243247
{

0 commit comments

Comments
 (0)