I'm building a react native app with Expo. The app displays a grid of images. On pressing an image, it transitions to a new route which contains a full-sized view of the image and additional data. The full-sized view is displayed in a FlatList, so the list of images can be swiped through. Navigating back from here returns to the grid.
The behavior I want to achieve is like the iOS photos app: Use a shared element transition on the image to transition into and out of the full-sized image view. This is straightforward if the user taps an image and then returns to the grid without swiping in the FlatList, because the shared element is the same both times.
Here it is working as intended:
However, if the user transitions to the full-sized view, swipes through the FlatList, then goes back, the shared element transition happens with the original element rather than the updated one. This video shows the issue:
I'm successfully keeping track of the correct shared element ID using the onViewableItemsChanged prop of FlatList. But given the arguments to the sharedElements function, it seems like I'd need to pass the id via the route params. Any way I do that, though, seems to cause unnecessary re-renders. How can I solve this and keep the sharedElements in sync?
Well, looks like I solved it. The answer was to set a param with the id of the shared element in each call to
navigation.navigate. This required using a custom "Back" button that sent params when going back to the grid view. Then theStacksetup can look like this:This way, when transitioning to the detail view, we always get the id of the shared element from the route params of the screen we're navigating to.
When navigating back to the grid view, prevent all the grid items from being unnecessarily re-rendered by using
memoanduseCallback.