Expo Router Link往返导航3次后失效:iOS无响应、Android崩溃
Expo Router 重复跳转后 Android 崩溃、iOS Link 失效问题
问题复现步骤与结果
- 登录页点击以下组件:
<Pressable style={styles.button}> <Link href='/register' style={styles.link}> <Text>Don't have an account?{'\n'}Register</Text> </Link> </Pressable>
结果:成功跳转至注册页(符合预期)。
- 注册页点击以下组件:
<Pressable style={styles.button}> <Link href='/login' style={styles.link}> <Text>Have an account?{'\n'}Login</Text> </Link> </Pressable>
结果:成功返回登录页(符合预期)。
- 重复步骤1(点击注册链接):
- iOS:iPhone模拟器中成功跳转至注册页(符合预期);
- Android:应用崩溃,报错:
The specified child already has a parent. You must call removeView() on the child's parent first.
- iOS端重复步骤2(点击登录链接):
结果:Link完全无响应,不再具备跳转功能。
环境信息
- 开发工具:Metro Bundler + Expo Go
- Web端无此问题
- 依赖版本:
"expo": "~52.0.18", "expo-router": "4.0.11", "react-native": "0.76.5"
解决方案
问题核心是Pressable嵌套Link导致的组件挂载冲突,Expo Router的Link本身已具备可点击交互能力,无需额外嵌套Pressable。
方案1:移除外层Pressable,直接使用Link
保留原样式,将Pressable的样式合并到Link上:
// 登录页跳转注册组件 <Link href='/register' style={[styles.button, styles.link]}> <Text>Don't have an account?{'\n'}Register</Text> </Link> // 注册页跳转登录组件 <Link href='/login' style={[styles.button, styles.link]}> <Text>Have an account?{'\n'}Login</Text> </Link>
方案2:保留Pressable,手动调用路由跳转
若需保留Pressable的额外交互逻辑,使用useRouter手动触发跳转:
import { useRouter } from 'expo-router'; // 组件内初始化路由实例 const router = useRouter(); // 登录页跳转注册的组件 <Pressable style={styles.button} onPress={() => router.push('/register')}> <Text style={styles.link}>Don't have an account?{'\n'}Register</Text> </Pressable> // 注册页跳转登录的组件 <Pressable style={styles.button} onPress={() => router.push('/login')}> <Text style={styles.link}>Have an account?{'\n'}Login</Text> </Pressable>
原因说明
- Expo Router的Link在原生端会映射为原生导航组件,嵌套Pressable会导致重复绑定点击事件,多次跳转后触发组件树挂载冲突(Android报错的直接原因);
- iOS端的无响应是因为多次交互后事件绑定失效,组件状态异常。
内容的提问来源于stack exchange,提问作者Emilio
相关产品推荐
相关产品推荐

