You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中Reanimated3的SharedTransitionTag失效问题(Expo51)

问题:Expo 51 + Reanimated 3 共享元素转场异常

在iPhone的Expo Go环境下,使用React Native结合Reanimated 3的sharedTransitionTag实现屏幕间共享元素转场时,出现以下问题:

  • 无预期的转场动画效果
  • 返回上一屏幕时,图片会从顶部突然消失

已验证两种路由方案(Expo Router、React-Navigation NativeStack),结果一致;将他人可正常运行的Expo 49示例代码升级到Expo 51后,同样出现该问题,推测是依赖版本兼容性导致。

相关代码

Screen 1

import Animated from "react-native-reanimated";
import { useRouter } from 'expo-router';
import { View, Text, Pressable } from 'react-native';

export default function Test() {
    const router = useRouter();
    return (
        <View>
            <Text>Test</Text>
            <Animated.Image
                source={require('./../../assets/ovelser/1-deadlift.png')}
                style={{height: 200, width: 200}}
                sharedTransitionTag="plis"
            />
            <Pressable
                onPress={() => router.push("/testend/1")}
                style={{backgroundColor: 'red', padding: 10, borderRadius: 5, marginTop: 10}}
            >
                <Text>Test</Text>
            </Pressable>
        </View>
    );
}

Screen 2

import Animated from "react-native-reanimated";
import { View, Text } from 'react-native';

export default function Testend() {
    return (
        <View>
            <Text>Test</Text>
            <Animated.Image
                source={require('./../../assets/ovelser/1-deadlift.png')}
                style={{height: 400, width: 400, top: 500}}
                sharedTransitionTag="plis"
            />
        </View>
    );
}

依赖列表

"dependencies": {
    "expo": "~51.0.20",
    "expo-constants": "~16.0.2",
    "expo-linking": "~6.3.1",
    "expo-router": "~3.5.18",
    "expo-status-bar": "~1.12.1",
    "frontend": "file:",
    "react": "18.2.0",
    "react-native": "^0.74.3",
    "react-native-countdown-circle-timer": "^3.2.1",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-pager-view": "^6.3.0",
    "react-native-paper": "^5.12.3",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "^4.10.1",
    "react-native-screens": "3.31.1",
    "react-native-shared-element": "^0.8.9"
  },

可能的修复方案

1. 调整Reanimated版本

Expo 51对应React Native 0.74.x,Reanimated 3.10.1可能在Expo Go环境存在sharedTransitionTag的适配bug。建议:

  • 降级Reanimated到~3.8.0(Expo 51初期推荐兼容版本),执行:
    npx expo install react-native-reanimated@~3.8.0 --fix
    
  • 或升级到Reanimated最新测试版,查看是否修复该问题。

2. 修改布局属性

Screen 2中图片使用top: 500绝对定位,可能导致Reanimated无法正确计算过渡路径。改用marginTop替代:

// Screen 2的Image style修改为
style={{height: 400, width: 400, marginTop: 500}}

3. 配置路由的Reanimated支持

对于Expo Router

在_layout.tsx中用Animated包裹Stack组件,确保转场动画能被Reanimated处理:

import { Stack } from 'expo-router';
import Animated from 'react-native-reanimated';

const AnimatedStack = Animated.createAnimatedComponent(Stack);

export default function RootLayout() {
  return <AnimatedStack />;
}

对于React-Navigation NativeStack

禁用默认导航动画,避免与共享元素转场冲突:

import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function AppNavigator() {
  return (
    <Stack.Navigator screenOptions={{ animation: 'none' }}>
      <Stack.Screen name="Test" component={Test} />
      <Stack.Screen name="Testend" component={Testend} />
    </Stack.Navigator>
  );
}

替代方案

1. 自定义Reanimated转场动画

手动控制动画逻辑,不受sharedTransitionTag限制:

  • 在两个屏幕中用Animated.View包裹图片
  • 通过路由参数或全局状态传递元素的初始位置、大小
  • 使用useAnimatedStyle结合withTiming实现位置、大小的平滑过渡

2. 使用react-native-shared-element手动触发转场

虽然react-navigation-shared-element已废弃,但react-native-shared-element本身仍可使用:

  • 用SharedElement包裹需要转场的图片,设置唯一id:
    import { SharedElement } from 'react-native-shared-element';
    
    // Screen 1
    <SharedElement id="plis">
      <Image source={...} style={...} />
    </SharedElement>
    
    // Screen 2
    <SharedElement id="plis">
      <Image source={...} style={...} />
    </SharedElement>
    
  • 在路由跳转时,手动调用转场方法(需结合导航生命周期监听)

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 07:49:55