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

搭配Redux使用React Navigation 6时navigation ref未就绪是什么原因?

核心原因

你调用NavRef.navigate的时机早于NavigationContainer完成初始化的时机。

具体执行顺序导致了这个问题:

  1. App组件渲染时,先挂载AuthProvider,再渲染NavigationContainer,最后渲染内部的ResolveAuthScreen
  2. ResolveAuthScreen的useEffect会在组件挂载完成后立刻执行tryLocalSignIn逻辑,而此时NavigationContainer的引用绑定、内部导航结构初始化还未完成,因此isReady()始终返回false。即使你通过AsyncStorage异步获取token,只要回调触发时导航容器还没完成初始化,就会出现这个问题。

另外你当前NavRef.js的navigate方法还有一个明显的逻辑错误:校验通过后你硬编码了跳转目标为TrackDetailScreen,直接忽略了传入的目标屏幕名称参数,后续修复时也要注意调整。


修复方案

方案1:等待导航容器就绪后再执行登录校验

在App.js中新增状态监听NavigationContainer的就绪事件,确认就绪后再渲染ResolveAuthScreen,确保调用导航方法时容器已经完成初始化:

// App.js 新增修改
import React, { useState } from 'react'
import { NavigationContainer } from '@react-navigation/native'
import 'react-native-gesture-handler'

// Provider
import { Provider as AuthProvider } from './src/context/AuthContext'

// Navigation
import { navigationRef } from './src/navigation/NavRef'

// Screens
import ResolveAuthScreen from './src/screens/ResolveAuthScreen'

const App = () => {
  const [isNavigationReady, setIsNavigationReady] = useState(false)
  return (
    <AuthProvider>
      <NavigationContainer 
        ref={navigationRef}
        onReady={() => setIsNavigationReady(true)}
      >
        {/* 只有导航容器就绪后才渲染校验页面,执行登录逻辑 */}
        {isNavigationReady && <ResolveAuthScreen />}
      </NavigationContainer>
    </AuthProvider>
  )
}

export default App

方案2:导航方法新增队列缓存未就绪时的请求

修改NavRef.js,对未就绪时的导航请求做缓存,等导航容器就绪后自动执行缓存的请求,不需要调整上层逻辑:

// NavRef.js 新增修改
import { createNavigationContainerRef } from '@react-navigation/native'

export const navigationRef = createNavigationContainerRef()
// 缓存未就绪时的导航请求
const pendingNavigations = []

// 监听容器就绪事件,批量执行缓存的导航请求
navigationRef.addListener('ready', () => {
  pendingNavigations.forEach(({ name, params }) => {
    navigationRef.navigate(name, params)
  })
  // 清空队列
  pendingNavigations.length = 0
})

export function navigate(name, params) {
  if (navigationRef.isReady()) {
    // 修复原来硬编码跳转目标的问题
    navigationRef.navigate(name, params)
  } else {
    pendingNavigations.push({ name, params })
  }
}

额外注意事项

需要确认你要跳转的TrackListScreen、SignUp等页面,已经在导航器的路由配置中完成注册,否则即使导航容器就绪,也会出现找不到路由的报错。

内容的提问来源于stack exchange,提问作者GʀᴜᴍᴘʏCᴀᴛ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:36:07