React native 如何在react导航中在不同嵌套堆栈之间导航 目标

React native 如何在react导航中在不同嵌套堆栈之间导航 目标,react-native,react-navigation,React Native,React Navigation,使用react navigation,从navigator中的屏幕导航到其他navigator中的屏幕 更多细节 如果我具有以下导航器结构: 父导航器 嵌套导航器1 屏幕A 屏幕B 嵌套导航器2 屏幕C 屏幕D 如何从嵌套导航器2下的屏幕D转到嵌套导航器1下的屏幕A?现在,如果我尝试导航。从屏幕D导航到屏幕A,将出现一个错误,表示它不知道屏幕A,只知道屏幕C和D 我知道在这个网站上的不同地方以及GitHub(,)都有人以不同的形式问过这个问题,但是对于如此基本的问题,没有明确的答

使用react navigation,从navigator中的屏幕导航到其他navigator中的屏幕

更多细节 如果我具有以下导航器结构:

  • 父导航器
    • 嵌套导航器1
      • 屏幕A
      • 屏幕B
    • 嵌套导航器2
      • 屏幕C
      • 屏幕D
如何从嵌套导航器2下的屏幕D转到嵌套导航器1下的屏幕A?现在,如果我尝试
导航。从屏幕D导航到屏幕A,将出现一个错误,表示它不知道屏幕A,只知道屏幕C和D

我知道在这个网站上的不同地方以及GitHub(,)都有人以不同的形式问过这个问题,但是对于如此基本的问题,没有明确的答案,滚动数百条GitHub评论来搜索解决方案并不好


也许这个问题可以为遇到这个非常常见问题的每个人编写一个代码。更新:有关React Navigation v5,请参阅


可以使用指定子动作

例如,如果要从嵌套导航器2下的屏幕D转到嵌套导航器1下的屏幕A:

this.props.navigation.navigate(
'嵌套导航器1',
{}, 
导航操作。导航({
routeName:“屏幕B”
})
)
同时检查:

在执行react native项目时,我遇到了同样的情况。我尝试了多种方法导航到屏幕,但失败了

经过多次尝试后,我尝试将家长导航对象传递给孩子,并进行了导航函数调用,结果成功了

现在谈到您的问题,如果您想从屏幕D导航到屏幕A,请遵循以下步骤

->使用屏幕道具将嵌套的navigator 2导航道具传递给其子级。

导出默认类主扩展组件{
静态导航选项={
标题:空
};
建造师(道具){
超级(道具);
此.state={
profileData:this.props.navigation.state.params,
路由索引:“”,
}
}
render(){
返回(
);
}
}
export const ParentNavigator=StackNavigator({
//屏幕名称:{screen:importedClassname}
Nested1:{屏幕:Nested1},
Nested2:{屏幕:nestes1}
});
export const nested1=StackNavigator({
ScreenA:{screen:ScreenA},
ScreenB:{screen:ScreenB}
});
export const nested2=StackNavigator({
ScreenC:{screen:ScreenC},
ScreenD:{screen:ScreenD}
});
您可以使用以下命令在子项中接收导航:

const{navigate}=this.props.screenProps.navigation;
现在,这个navigate()可以用于在子级之间导航

我承认这个过程有点令人困惑,但我找不到任何解决方案,所以我不得不这样做,因为我必须完成我的要求

完全自由:带导航选项的单身人士 如果您有一个拥有多个导航堆栈和子堆栈的情况,那么在给定如何设置React navigation的情况下,知道如何获取对所需堆栈的引用可能会令人沮丧。如果您能够在任何给定的时间简单地引用任何特定的堆栈,这将更容易。这是怎么做的

  • 创建特定于要在任何位置引用的堆栈的单例

    // drawerNavigator.js . (or stackWhatever.js)
    const nav = {}
    export default {
      setRef: ref => nav.ref = ref,
      getRef: () => nav.ref
    }
    
  • 使用navigatorOptions设置所需导航器上的参考

    import { createBottomTabNavigator } from 'react-navigation'
    import drawerNavigation from '../drawerNavigator'
    
    const TabNavigation = createBottomTabNavigator(
      {
        // screens listed here
      },
      {
        navigationOptions: ({ navigation }) => {
          // !!! secret sauce set a reference to parent
          drawerNavigation.setRef(navigation)
          return {
            // put navigation options
          }
        }
      }
    )
    
  • 现在,您可以在内部或外部的任何位置引用
    drawerNavigator

    // screen.js
    import drawerNavigator from '../drawerNavigator'
    
    export default class Screen extends React.Component {
      render() {
        return (
          <View>
            <TouchableHighlight onPress={() => drawerNavigator.getRef().openDrawer()}>
              <Text>Open Drawer</Text>
            </TouchableHighlight>
          </View>
        )
      }
    }
    
    //screen.js
    从“../drawerNavigator”导入drawerNavigator
    导出默认类屏幕扩展React.Component{
    render(){
    返回(
    paurernavigator.getRef().openDrawer()}>
    抽屉
    )
    }
    }
    
  • 解释

    function Root() {
      return (
        <Stack.Navigator>
          <Stack.Screen name="Profile" component={Profile} />
          <Stack.Screen name="Settings" component={Settings} />
        </Stack.Navigator>
      );
    }
    
    function App() {
      return (
        <NavigationContainer>
          <Drawer.Navigator>
            <Drawer.Screen name="Home" component={Home} />
            <Drawer.Screen name="Root" component={Root} />
          </Drawer.Navigator>
        </NavigationContainer>
      );
    }
    
    navigation.navigate('Root', { screen: 'Settings' });
    

    在步骤2中,选项卡导航器是抽屉导航器中的一个屏幕。Tab Navigator需要关闭抽屉,但也需要关闭应用程序中的任何位置。执行此步骤后,您可以调用
    drawerNavigator.getRef().closeDrawer()
    。在这一步之后,您不仅可以直接访问props.navigation。

    我还找到了这样的解决方案:

    onPress={()=>
    我保证([
    导航调度(
    导航操作。重置({
    索引:0,
    //TabNav是嵌套在StackNavigator中的TabNavigator
    操作:[NavigationActions.navigate({routeName:'TabNav'})]
    })
    )
    ])。然后(()=>navigation.navigate('specificScreen'))
    }
    
    反应导航v3:

    Navigation.navigate
    现在将一个对象作为参数。设置堆栈名称,然后导航到该堆栈中的路由,如下所示

    navigation.navigate(NavigationActions.navigate({
        routeName: 'YOUR_STACK',
        action: NavigationActions.navigate({ routeName: 'YOUR_STACK-subRoute' })
    }))
    
    其中“YOUR_STACK”是在创建堆栈时调用的任何堆栈

      YOUR_STACK: createStackNavigator({ subRoute: ... })
    

    LoggedOut
    是登录屏幕所在的堆栈名称。

    我的目标是让所有身份验证屏幕共享相同的背景,并使用常规堆栈转换实现应用程序的其余部分

    几个小时后,我发现解决方案是将
    createStackNavigator()
    与组件包装器放在同一个文件中。这样您就可以成功地公开所述的
    静态路由器
    。这将避免出现
    在应用程序中只显式呈现一个导航器的警告,您可以使用
    This.props.navigation.navigate('AnyScreen')
    导航到任何嵌套屏幕

    AuthRouter.js

    RootContainer.js

    从“../Config/Router”导入{RootNavigationStack};
    类RootContainer扩展组件{
    render(){
    返回;
    }
    }
    
    注:

    • header:null
      RootNaviagtionStack
      传递到嵌套堆栈以删除重叠的头

    • 如果从嵌套A导航到N
      export const MessengerStackNavigator = createStackNavigator(
        {
          Chat: {
            screen: Chat,
          },
          User: {
            screen: User,
          },
        }
      );
      
      export default class MainContainer extends React.Component {
        constructor( props ) {
          super( props );
        }
      
        static router = MessengerStackNavigator.router;
      
        render() {
          return <MessengerStackNavigator navigation={ this.props.navigation } />;
        }
      }
      
      import { createStackNavigator } from 'react-navigation';
      
      import AuthRouter from './AuthRouter';
      import MessengerRouter from './MessengerRouter';
      
      export const RootNavigationStack = createStackNavigator( {
        AuthContainer: {
          screen: AuthRouter,
          navigationOptions: () => ( {
            header: null
          } )
        },
        MessengerRouter: {
          screen: MessengerRouter,
          navigationOptions: () => ( {
            header: null
          } )
        }
      } );
      
      import { RootNavigationStack } from '../Config/Router';
      
      class RootContainer extends Component {
      
        render() {
          return <RootNavigationStack />;
        }
      }
      
        const subNavigateAction = NavigationActions.navigate({
          routeName: 'NestedNavigator1.1',
          action: NavigationActions.navigate({
            routeName: 'ScreenB',
            params: {},
          }),
        });
        const navigateAction = NavigationActions.navigate({
          routeName: 'NestedNavigator1',
          action: subNavigateAction,
        });
        this.props.navigation.dispatch(navigateAction);
      
      global.stackNavigator.dispatch(
         NavigationActions.navigate({
             routeName: 'Player',
             params: { },
         }),
      );
      
      Parent Navigator
        Nested Navigator 1
          screen A
          screen B
        Nested Navigator 2
          screen A
          screen C
          screen D
      
      navigation.navigate('Nested Navigator 2', { screen: 'screen D' });
      
      navigation.navigate('Nested Navigator 2', {
          screen: 'Nested Navigator 3', params: {
              screen: 'screen E'
          }
      });
      
      function Root() {
        return (
          <Stack.Navigator>
            <Stack.Screen name="Profile" component={Profile} />
            <Stack.Screen name="Settings" component={Settings} />
          </Stack.Navigator>
        );
      }
      
      function App() {
        return (
          <NavigationContainer>
            <Drawer.Navigator>
              <Drawer.Screen name="Home" component={Home} />
              <Drawer.Screen name="Root" component={Root} />
            </Drawer.Navigator>
          </NavigationContainer>
        );
      }
      
      navigation.navigate('Root', { screen: 'Settings' });
      
      this.props.navigation.navigate(
                'Nested Navigator 1',
                {name: 'jane'},
                this.props.navigation.navigate('Screen A', {id: 2219}),
              );
      
      navigation.navigate('Root', {
        screen: 'Settings',
        params: {
          screen: 'Sound',
          params: {
            screen: 'Media',
          },
        },
      });
      
      navigation.navigate('Home', {
         screen: 'Profile',
         params: {userID: 1}
       }
      )
      
      NAVIGATOR:
        *StackA
          *ScreenC
          *ScreenD
        *StackB
          *ScreenI
          *StackE
            *ScreenF
            *StackG
              *ScreenJ
              *ScreenH
      
      navigation.navigate('StackB',{
         screen: 'StackE',
         params: {
            screen: 'StackG',
            params: {
               screen: 'ScreenH'
            }
         }
        }
      )