React Navigation问题:如何从父视图导航StackNavigator?
你应该是想在TabIndex父组件里触发子组件StackIndex(StackNavigator)的页面跳转吧?直接调用this.props.navigation.navigate('Screen2')肯定行不通——因为TabIndex拿到的是Tab导航的navigation对象,它的导航栈里并没有Screen2,这个页面属于子Stack导航的栈。
下面给你几个实用的解决方案:
方案一:通过Ref获取子Stack的Navigation对象
给StackIndex组件添加ref,直接调用它的导航方法:
const StackIndex = StackNavigator({ Screen1: { screen: Screen1 }, Screen2: { screen: Screen2 }, Screen3: { screen: Screen3 } }) class TabIndex extends Component { // 创建ref引用StackIndex组件 stackRef = React.createRef(); handleNavigateToScreen2 = () => { // 通过ref拿到子Stack的navigation并跳转 this.stackRef.current?.navigation.navigate('Screen2'); } render(){ return( <View> <TouchableWithoutFeedback onPress={this.handleNavigateToScreen2}> <Text>{'Navigate to Screen 2.'}</Text> </TouchableWithoutFeedback> {/* 给StackIndex绑定ref */} <StackIndex ref={this.stackRef} /> </View> ) } }
方案二:将子Stack的Navigation传递给父组件
在子Stack的默认屏幕(比如Screen1)里,把navigation通过回调传递给父组件:
首先修改Screen1组件:
class Screen1 extends Component { componentDidMount() { // 把当前Stack的navigation传给父组件TabIndex this.props.onGetNavigation(this.props.navigation); } render() { // 你的Screen1页面内容 return <View><Text>Screen 1</Text></View>; } }
然后在TabIndex里接收并使用这个navigation:
class TabIndex extends Component { state = { stackNavigation: null } handleNavigateToScreen2 = () => { this.state.stackNavigation?.navigate('Screen2'); } render(){ return( <View> <TouchableWithoutFeedback onPress={this.handleNavigateToScreen2}> <Text>{'Navigate to Screen 2.'}</Text> </TouchableWithoutFeedback> <StackIndex screenProps={{ onGetNavigation: (nav) => this.setState({stackNavigation: nav}) }} /> </View> ) } }
方案三:全局导航服务(推荐)
创建一个全局的NavigationService,摆脱组件层级限制,任何组件都能直接调用导航:
- 新建
NavigationService.js文件:
import { NavigationActions } from 'react-navigation'; let _navigator; function setTopLevelNavigator(navigatorRef) { _navigator = navigatorRef; } function navigate(routeName, params) { _navigator.dispatch( NavigationActions.navigate({ routeName, params, }) ); } // 可按需添加goBack、reset等其他导航方法 export default { navigate, setTopLevelNavigator, };
- 在根组件里初始化服务:
import NavigationService from './NavigationService'; class App extends Component { render() { return ( <StackIndex ref={(navigatorRef) => { NavigationService.setTopLevelNavigator(navigatorRef); }} /> ); } }
- 在
TabIndex里直接调用:
import NavigationService from './NavigationService'; class TabIndex extends Component { handleNavigateToScreen2 = () => { NavigationService.navigate('Screen2'); } render(){ return( <View> <TouchableWithoutFeedback onPress={this.handleNavigateToScreen2}> <Text>{'Navigate to Screen 2.'}</Text> </TouchableWithoutFeedback> <StackIndex /> </View> ) } }
这个方案灵活性最高,不管组件层级多深,都能轻松触发跳转。
内容的提问来源于stack exchange,提问作者Seyha
相关产品推荐
相关产品推荐

