Skip to content

Commit 7dcedf1

Browse files
Atharv Sonimeta-codesync[bot]
authored andcommitted
Fix iOS shadow recycling bug causing duplicate shadows (#54204) (#54484)
Summary: Fix iOS shadow recycling bug causing duplicate shadows (#54204) - Add comprehensive visual layer cleanup in prepareForRecycle method - Clean up _boxShadowLayers, _backgroundColorLayer, _borderLayer, _outlineLayer, _filterLayer - Prevents cross-component contamination of visual effects during component recycling - Fixes duplicate shadow issue when navigating to the same screen multiple times Resolves: #54204 This PR fixes a critical iOS-specific bug where duplicate shadows appear on random views when navigating to the same screen multiple times. The issue occurs because the `prepareForRecycle` method in `RCTViewComponentView` was not properly cleaning up visual layers during component recycling, causing shadow layers and other visual effects to persist and contaminate recycled components. The root cause was that visual layers (`_boxShadowLayers`, `_backgroundColorLayer`, `_borderLayer`, etc.) were not being removed from their superlayers or nullified during component recycling, leading to cross-component contamination of visual effects. ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [IOS] [FIXED] - Fix duplicate shadow bug during component recycling by cleaning up visual layers in prepareForRecycle Pull Request resolved: #54484 Test Plan: 1. **Existing Tests**: All existing React Native tests pass with this change ```bash yarn test --testPathPattern="View" --passWithNoTests --maxWorkers=2 # Result: 9 test suites passed, 99 tests passed Issue Reproduction: The fix addresses the specific scenario described in #54204: Navigate to a screen with shadow styles Navigate back Navigate to the same screen again Before: Duplicate overlapping shadows appear After: Only correct shadows are displayed Memory Safety: The fix properly removes layers from superlayers and nullifies references to prevent memory leaks Comprehensive Coverage: The fix addresses not just box shadows but all visual layers to prevent similar issues with borders, outlines, filters, and background images The implementation follows the same cleanup pattern used in the invalidateLayer method, ensuring consistency with existing codebase patterns. ``` Reviewed By: jorge-cab Differential Revision: D86769588 Pulled By: joevilches fbshipit-source-id: bdeda5e10ddc7e23b139f3a953b5634b06766a1e
1 parent ca077c6 commit 7dcedf1

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,26 @@ - (void)prepareForRecycle
623623
self.layer.opacity = (float)props.opacity;
624624
}
625625

626+
// Clean up box shadow layers to prevent cross-component contamination
627+
if (_boxShadowLayers != nullptr) {
628+
for (CALayer *boxShadowLayer = nullptr in _boxShadowLayers) {
629+
[boxShadowLayer removeFromSuperlayer];
630+
}
631+
[_boxShadowLayers removeAllObjects];
632+
_boxShadowLayers = nil;
633+
}
634+
635+
// Clean up other visual layers
636+
[_backgroundColorLayer removeFromSuperlayer];
637+
_backgroundColorLayer = nil;
638+
[_borderLayer removeFromSuperlayer];
639+
_borderLayer = nil;
640+
[_outlineLayer removeFromSuperlayer];
641+
_outlineLayer = nil;
642+
[_filterLayer removeFromSuperlayer];
643+
_filterLayer = nil;
644+
[self clearExistingBackgroundImageLayers];
645+
626646
_propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = nil;
627647
_eventEmitter.reset();
628648
_isJSResponder = NO;

0 commit comments

Comments
 (0)