react-navigation-shared-element
react-navigation-shared-element copied to clipboard
Shared element transition only works one time
bug
- The shared element only works the first time after the app opens.
- When going back from the detail screen, it's also not animated.
Expected behavior
The shared element transition works on all cards and when going back
Demo
https://user-images.githubusercontent.com/36442007/135582689-e0d557b5-f31f-4e88-884b-ce5d74958afa.mov
Code
app.tsx
const RootStack = createSharedElementStackNavigator()
return (
<RootStack.Navigator
initialRouteName="TabNav"
screenOptions={{
headerShown: false,
}}
>
<RootStack.Screen name="TabNav" component={TabNav} />
<RootStack.Screen
name="ProductDetail"
component={ProductDetail}
sharedElements={route => {
const { params } = route
return ['headerImage' + params.id]
}}
options={{
cardStyleInterpolator: ({ current: { progress } }) => {
return { cardStyle: { opacity: progress } }
},
}}
/>
</RootStack.Navigator>
)
Card.tsx
const ProductCard: FC<Props> = ({ product, style }) => {
const navigation = useNavigation()
const price = useLocalizePrice(priceDetails?.price, priceDetails.currency)
return (
<View
testID={'product-card-' + name}
style={style}
onPress={() =>
//@ts-ignore
navigation.navigate('ProductDetail', {
id: product.id,
})
}
>
<View>
<SharedElement id={`headerImage${id}`}>
<Image
source={{
uri: images.mainPicture,
}}
resizeMode="cover"
/>
</SharedElement>
</View>
</View>
)
}
Detail.tsx
export default function ProductDetail() {
const { params } = useRoute<RouteProp<ParamList, 'productDetail'>>()
const { id } = params
const { bottom } = useSafeAreaInsets()
const scrollY = useRef(new Animated.Value(0)).current
const onScroll = Animated.event(
[
{
nativeEvent: {
contentOffset: {
y: scrollY,
},
},
},
],
{
useNativeDriver: true,
}
)
return (
<View bottom={bottom} testID="product-detail">
<Animated.ScrollView
showsVerticalScrollIndicator={false}
onScroll={onScroll}
>
<SharedElement id={`headerImage${id}`} style={{ flex: 1 }}>
<Image source={{ uri: images[0] }} />
</SharedElement>
</Animated.ScrollView>
</View>
)
}
I got the exact same issue... here are my versions in case it helps:
"react-native-shared-element": "0.7.0",
"react-navigation-shared-element": "^3.1.3",
"@react-navigation/native": "~5.9.2",
"@react-navigation/stack": "^5.14.5",
"react-native-screens": "~3.4.0",
Hi, this problem is not specific to the native extensions, but to react-navigation. Moving this to the react-navigation-shared-element repo
I'm sorry this answer seems so late, but, only those who come later. I faced the same problem and the reason was I have two Stack in my app. One with react-navigation's createStackNavigator and the other with createSharedElementStackNavigator and the shared element transition only works the first time. After bringing both back to createSharedElementStackNavigator. Everything works fine. So try to check your project again
hi @phuctranba
I'll definitely try this, I stopped using react-navigation-shared-element for this reason 😅
thanks!
A late response from me as well but my issue was that I have my Stack navigator nested inside a Bottom tabs navigator which resulted in the sharedElements prop of the stack screen getting called with the current route only on the first navigation. Taking the screen out of the Bottom tabs worked but it might mess with your overall navigation architecture :(