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

Expo Router Link往返导航3次后失效:iOS无响应、Android崩溃

问题复现步骤与结果

  1. 登录页点击以下组件:
<Pressable style={styles.button}>
  <Link href='/register' style={styles.link}>
    <Text>Don't have an account?{'\n'}Register</Text>
  </Link>
</Pressable>

结果:成功跳转至注册页(符合预期)。

  1. 注册页点击以下组件:
<Pressable style={styles.button}>
  <Link href='/login' style={styles.link}>
    <Text>Have an account?{'\n'}Login</Text>
  </Link>
</Pressable>

结果:成功返回登录页(符合预期)。

  1. 重复步骤1(点击注册链接):
  • iOS:iPhone模拟器中成功跳转至注册页(符合预期);
  • Android:应用崩溃,报错:The specified child already has a parent. You must call removeView() on the child's parent first.
  1. 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。

保留原样式,将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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 13:52:38