react-native-reanimated
react-native-reanimated copied to clipboard
[V3][iOS] Shared element transitions in nested stack stop working after navigation to parent stack,
Description
I'm using the latest expo router (v3.4.6) and have a expo router folder layout like follows:
(modals) (tabs)
Inside (tabs) there is a stack navigator with two screens where I have set up shared element transitions between the pages in the stack.
Everything works as expected until I navigate to a screen on the parent stacks (like a different tab or a screen in (modals)) at which point the shared element transitions stop working and goes back to the default animation without a shared element transition as can be seen from the examples below. (minimal reproducible demo linked).
The only workaround to this that I have found is resetting the animated component with a shared transition with a "key" prop every time the screen is focused, this makes the shared element work no matter where I navigate to, but obviously introduces flashing and unnecessary re-rendering. I've checked the same build on an android device but it works correctly.
This only happens AFTER the screen with the shared element transition has already been mounted once. If you navigate to a screen on those same parent stack navigators before navigating to where the shared element transitions are, it will still work, but only once.
Big thanks to the reanimated team for shared element transitions, they look and feel great apart from this issue. Perhaps it's an expo router thing.
https://github.com/software-mansion/react-native-reanimated/assets/149704513/8cb2671b-903e-4c8e-a9fa-41c283fea20a
https://github.com/software-mansion/react-native-reanimated/assets/149704513/719b44b8-499b-4cb0-8a44-51ede1c7ea32
Steps to reproduce
- Create a new expo project with create-expo-app
- Create a tab layout that has a nested stack navigator as one of it's screens.
- Create two pages in the stack navigator.
- Add shared element transitions between them.
- Navigate to stack with shared element transitions - works.
- Navigate to different tab in bottom tab navigator and navigate back to shared element stack - stops working.
Snack or a link to a repository
https://github.com/CalypsoTechLTD/shared-element-transition-issue
Reanimated version
3.6.2
React Native version
0.73.2
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Expo Dev Client
Architecture
Fabric (New Architecture)
Build type
Debug app & dev bundle
Device
Real device
Device model
iPhone 14 Pro (iOS 17.3)
Acknowledgements
Yes
After some research, I believe this has to do with the fact that the unregisterTransition only gets called on component unmount, and in most navigators once the screens are mounted, they don't unmount. This behaviour stops and the SET starts working again, if you call
SharedTransition.prototype.registerTransition(viewTag, sharedElementTag)
manually on focus, and
SharedTransition.prototype.unregisterTransition(viewTag)
manually when the screen is not focused. This however makes the animation very jittery and I do not recommend. For anyone interested in a temporary hotfix, I suggest updating the key prop of the component to be animated whenever the screen the user is on, is not one of the shared element ones. In my application, it looks something like this:
const pathname = usePathname();
const shouldUpdate = !pathname.includes("events");
const [key, setKey] = useState(0);
useEffect(() => {
if (shouldUpdate) {
setKey((prev) => prev + 1);
}
}, [pathname]);
It would still be good to get some insight on this, we're happy to submit a PR if we get some more understanding on it.
It would be great to get an answer on this, I am struggling with this also.
any insights into this? @CalypsoTechLTD the key hotfix only works for me if I navigate between the screen with the animated component and a sibling screen twice in a row, which seems strange? then subsequent navigation works.
EDIT: ok, figured out my problem, even with the key prop hotfix, if I navigate to a screen that uses this library https://github.com/dohooo/react-native-reanimated-carousel it completely breaks shared element transitions once I go back.
any solution now?
any insights into this? @CalypsoTechLTD the key hotfix only works for me if I navigate between the screen with the animated component and a sibling screen twice in a row, which seems strange? then subsequent navigation works.
EDIT: ok, figured out my problem, even with the key prop hotfix, if I navigate to a screen that uses this library https://github.com/dohooo/react-native-reanimated-carousel it completely breaks shared element transitions once I go back.
@alaughlin I think I’m having this same issue with react-native-carousel, but to know for sure I need to remove it from my code, update key of elements and test going back without carousel. Will keep you posted. Basically for me after changing key and shareTransitionTag props I am experiencing the correct element animate back to original position but it gets frozen in that original position forevermore.
Any updates on this issue?
Also hoping for updates here. Have tried implementing useIsFocused and modifying the key, also trying to force a re-render based on useIsFocused, no luck.
+1