在两个堆栈之间传递参数-React Native

时间:2018-12-29 16:06:11

标签: android react-native mobile-development

我的应用应具有Google的登录屏幕,因此登录后进入菜单屏幕。

在验证后进入菜单屏幕后,为了不按返回按钮时不返回登录屏幕。 我已经将堆栈分开,一个用于登录,另一个用于其他屏幕

在App.js中:

const AuthStack = createStackNavigator({
  LoginSplashScreen: LoginSplashScreen 
});
const AppStack = createStackNavigator({ 
  MenuScreen:MenuScreen,
  DetailsScreen: DetailsScreen,
  PhotoScreen: PhotoScreen,
  DocumentScreen: DocumentScreen,
  AudioScreen: AudioScreen,
  ScheduleScreen: ScheduleScreen,
  SettingsScreen: SettingsScreen,
  FilesScreen: FilesScreen,
  GalleryScreen: GalleryScreen
   });


const Root= createAppContainer(createSwitchNavigator(
  {
    AuthStack:AuthStack,
    AppStack:AppStack
  },
  {
    initialRouteName: 'AuthStack',
  }
));

export default class App extends React.Component {
  render() {
    return (
      <Root/>  
    )
  }
}

因此在LoginSplashScreen中 验证后,我使用以下代码进行导航:

    this.props.navigation.navigate('AppStack', {
      signedIn: true,
      name: result.user.name,
      photoUrl: result.user.photoUrl
    });

导航效果很好,但是参数'name','signedIn','photoUrl' 禁止通过 实际上,在提醒时

    Alert.alert('',JSON.stringify(this.props.navigation.state.params))

在菜单屏幕(第二叠)上,它为空

我在做什么错了?

为什么我的参数没有传递?因为我可能需要其他抽屉式导航。

是否可以为应用程序中的所有屏幕设置全局参数?

是否有更好的方法来避免在菜单屏幕上按回并且不获得登录屏幕?

编辑:

我设法通过设置全局参数来解决此特定问题:

global.param= result.param;

但是,我仍然需要一个答案才能在2个单独的堆栈之间传递

3 个答案:

答案 0 :(得分:5)

通过创建两个单独的堆栈,您已经分离了params范围,您想要做的是:使用不同的导航范围将params发送到完全不同的导航范围,这实际上并没有意识到上一个在一个共同的父母中。

当您使用this.props.navigation中的LoginSplashScreen时,实际上您位于AuthStack的沙盒导航范围中,该范围仅限于其自己的导航器路线。现在,当您将两个堆栈作为SwitchNavigator的Routes绑定到一个导航器中时,您将进入一个父导航器的作用域,该作用域提供了自己的导航道具,因此如果您使用navigation开关导航器的道具,那么您将在AppStack中获得这些参数,但是自那以后。

我建议的是以下三种正确执行方法:

  1. 将登录屏幕用作SwitchNavigator的直接路由,从而删除了无用的登录堆栈导航器,从而断开了路由。

代码应类似于:

const Root= createAppContainer(createSwitchNavigator({
   LoginSplashScreen: LoginSplashScreen 
   AppStack:AppStack
}, {
initialRouteName: 'LoginSplashScreen',
}));
  1. 使用redux将数据存储在通常可访问的存储中,并按照另一个答案中的说明在不同组件上使用它,但这不是主要使用redux的原因。

  2. 在交换机导航器中使用新组件代替AppStack,同时将LoginSplashScreen作为SwitchNavigator的直接路径之一,并在新组件内部渲染AppStack并传递在params中以screenProps的形式收到AppStack,然后只需在堆栈路由中使用screenProps。

代码应类似于:

 const Root= createAppContainer(createSwitchNavigator({
   LoginSplashScreen: LoginSplashScreen, 
   MyMediatorScreen: MyFancyComponent
}, {
initialRouteName: 'AuthStack',
}));

例如FancyComponent将如下所示:

class MyFancyComponent extends React.Component{
   constructor (props){
      super (props); 
   }

   render () {
     const {params} = this.props.navigation.state;
     return (
        <AppStack screenProps = {params} />
     )
   }
}

答案 1 :(得分:0)

据我在您的代码中看到的,一切似乎都很好,可能是您正在JSON.string化它,也许尝试分别获取每个参数,即this.props.navigation.getParam('signedIn', false);

对于使用react-navigation的身份验证流程,您应该遵循以下指南:https://reactnavigation.org/docs/en/auth-flow.html,这样一来,登录后就不会出现后退按钮。

对于存储数据(例如您从Google获得的身份验证响应),我建议使用AsyncStorage或其他形式的存储库(例如react-redux)。这是一个非常简单的示例,它使用react-reduxhttps://medium.com/@aurelie.lebec/redux-and-react-native-simple-login-example-flow-c4874cf91dde

我个人建议使用一种存储系统,因为您的整个应用程序都可以访问auth状态,而不必不断地将其作为参数发送。

答案 2 :(得分:0)

在某些情况下,您不想将堆栈分开以分离关注点,或者在您的情况下,您可以在这里做的是通过嵌套导航器传递参数,如此处的 react navigators 文档中所述React Navigator Docs< /p>

在你的情况下,我会发送参数:

this.props.navigation.navigate('AppStack', { screen: 'MenuScreen', params: { signedIn: true, name: result.user.name, photoUrl: result.user.photoUrl }, });

希望这对以后的人有所帮助。我已经对此进行了测试,因为我有一个确切的实现。