如何在组件层级外获取嵌套StackNavigator的navigation对象?
可以通过Stack导航器的onReady回调直接拿到嵌套导航的navigation对象,无需通过子组件传递,以下是两种实用实现方式:
方法一:使用useRef + onReady回调
利用Stack.Navigator的onReady属性(导航器初始化完成后触发,参数即为嵌套导航的navigation实例),结合useRef存储该实例:
import { createStackNavigator } from '@react-navigation/stack'; import { useRef } from 'react'; export function AddDeviceWizard({ navigation: rootNavigation }) { const Stack = createStackNavigator(); const nestedNavRef = useRef(null); return ( <BaseScreen navigator={nestedNavRef.current}> <Stack.Navigator initialRouteName="addDevice1" // 导航器就绪时,将嵌套navigation存入ref onReady={(navigation) => { nestedNavRef.current = navigation; }} > <Stack.Screen name="addDevice1" component={AddDevice1} /> <Stack.Screen name="addDevice2" component={AddDevice2} /> </Stack.Navigator> </BaseScreen> ); }
注意:组件首次渲染时
nestedNavRef.current为null,如果BaseScreen需要立即使用该实例,可以在内部做非空判断,或者改用useState替代useRef,这样实例更新时会触发组件重渲染:
import { createStackNavigator } from '@react-navigation/stack'; import { useState } from 'react'; export function AddDeviceWizard({ navigation: rootNavigation }) { const Stack = createStackNavigator(); const [nestedNavigation, setNestedNavigation] = useState(null); return ( <BaseScreen navigator={nestedNavigation}> <Stack.Navigator initialRouteName="addDevice1" onReady={(navigation) => { setNestedNavigation(navigation); }} > <Stack.Screen name="addDevice1" component={AddDevice1} /> <Stack.Screen name="addDevice2" component={AddDevice2} /> </Stack.Navigator> </BaseScreen> ); }
方法二:封装嵌套导航器组件
把嵌套Stack导航器封装成独立组件,在内部通过useNavigation获取嵌套实例,再通过回调传递给父组件:
import { createStackNavigator, useNavigation } from '@react-navigation/stack'; import { useEffect } from 'react'; // 封装嵌套导航器组件 function NestedAddDeviceStack({ onNavReady }) { const Stack = createStackNavigator(); const nestedNavigation = useNavigation(); // 组件挂载后,将嵌套navigation传递给父组件 useEffect(() => { onNavReady(nestedNavigation); }, [onNavReady, nestedNavigation]); return ( <Stack.Navigator initialRouteName="addDevice1"> <Stack.Screen name="addDevice1" component={AddDevice1} /> <Stack.Screen name="addDevice2" component={AddDevice2} /> </Stack.Navigator> ); } export function AddDeviceWizard({ navigation: rootNavigation }) { const [nestedNavigation, setNestedNavigation] = useState(null); return ( <BaseScreen navigator={nestedNavigation}> <NestedAddDeviceStack onNavReady={setNestedNavigation} /> </BaseScreen> ); }
以上两种方式都能避免通过子组件+Context传递的繁琐流程,直接在父组件层面拿到嵌套导航的navigation实例。
内容的提问来源于stack exchange,提问作者AleH
相关产品推荐
相关产品推荐

